Compare commits

..

3 Commits

Author SHA1 Message Date
Yang Chen 2174e7a027 Merge branch 'master' into release/v1
* master:
  Prepare for release 1.0.2
  Increase emulator boot timeout to 5 mins.
  Update npm packages.
2019-11-30 22:17:06 +11:00
Yang Chen 6097e0ab6c Merge branch 'master' into release/v1
* master:
  Switch to sh.
  Update README.md
  Fix typos in docs.
2019-11-24 17:54:22 +11:00
Yang Chen 483b89e0bf Release v1. 2019-11-09 20:27:51 +11:00
24 changed files with 338 additions and 719 deletions
+2 -6
View File
@@ -4,8 +4,6 @@ on:
push: push:
branches: branches:
- master - master
paths-ignore:
- '**.md'
jobs: jobs:
test: test:
@@ -34,8 +32,6 @@ jobs:
target: google_apis target: google_apis
arch: x86_64 arch: x86_64
profile: Nexus 6 profile: Nexus 6
emulator-options: -no-window -no-snapshot -noaudio -no-boot-anim -camera-back none headless: true
disable-animations: true disable-animations: true
script: | script: adb devices -l
adb reconnect
adb devices -l
-9
View File
@@ -1,14 +1,5 @@
# Change Log # Change Log
## v2.1.0
* Added support for multi-line script.
## v2.0.0
* Added action input `emulator-options` for providing command-line options used when launching the emulator. Default value is `-no-window -no-snapshot -noaudio -no-boot-anim`.
* Removed `headless` action input which is equivalent to specifying `-no-window` in the new `emulator-options` action input (included by default).
## v1.0.2 ## v1.0.2
* Increased emulator boot timeout to **5 mins**. * Increased emulator boot timeout to **5 mins**.
+4 -6
View File
@@ -6,7 +6,7 @@
A GitHub Action for installing, configuring and running Android Emulators on macOS virtual machines. A GitHub Action for installing, configuring and running Android Emulators on 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 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.
The **masOS** 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 **masOS** 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.
@@ -37,7 +37,7 @@ jobs:
fetch-depth: 1 fetch-depth: 1
- name: run tests - name: run tests
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v1
with: with:
api-level: 29 api-level: 29
script: ./gradlew connectedCheck script: ./gradlew connectedCheck
@@ -60,7 +60,7 @@ jobs:
fetch-depth: 1 fetch-depth: 1
- name: run tests - name: run tests
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v1
with: with:
api-level: ${{ matrix.api-level }} api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }} target: ${{ matrix.target }}
@@ -77,8 +77,6 @@ jobs:
| `target` | Optional | `default` | Target of the system image - `default` or `google_apis`. | | `target` | Optional | `default` | Target of the system image - `default` or `google_apis`. |
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86` or `x86_64`. | | `arch` | Optional | `x86` | CPU architecture of the system image - `x86` or `x86_64`. |
| `profile` | Optional | N/A | Hardware profile used for creating the AVD - e.g. `Nexus 6`. For a list of all profiles available, run `$ANDROID_HOME/tools/bin/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 `$ANDROID_HOME/tools/bin/avdmanager list` and refer to the results under "Available Android Virtual Devices". |
| `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-snapshot -camera-back emulated`. | | `headless` | Optional | `true` | Whether to launch emulator without UI - `true` or `false`. When set to `true` this is equivalent to running the emulator with `emulator -no-window`. |
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. | | `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
| `script` | Required | N/A | Custom script to run - e.g. to run Android instrumented tests on the emulator: `./gradlew connectedCheck` | | `script` | Required | N/A | Custom script to run - e.g. to run Android instrumented tests on the emulator: `./gradlew connectedCheck` |
Default `emulator-options`: `-no-window -no-snapshot -noaudio -no-boot-anim`.
+21
View File
@@ -77,6 +77,27 @@ describe('arch validator tests', () => {
}); });
}); });
describe('headless validator tests', () => {
it('Throws if headless is not a boolean', () => {
const func = () => {
validator.checkHeadless('yes');
};
expect(func).toThrowError(`Input for input.headless should be either 'true' or 'false'.`);
});
it('Validates successfully if headless is either true or false', () => {
const func1 = () => {
validator.checkHeadless('true');
};
expect(func1).not.toThrow();
const func2 = () => {
validator.checkHeadless('false');
};
expect(func2).not.toThrow();
});
});
describe('disable-animations validator tests', () => { describe('disable-animations validator tests', () => {
it('Throws if disable-animations is not a boolean', () => { it('Throws if disable-animations is not a boolean', () => {
const func = () => { const func = () => {
-33
View File
@@ -1,33 +0,0 @@
import * as parser from '../src/script-parser';
describe('script parser tests', () => {
it('Scripts are trimmed', () => {
const script = ` command \n`;
expect(parser.parseScript(script)).toEqual(['command']);
});
it('Commented lines are filtered out', () => {
const script = `
# command1
command2
# command3
command4
`;
expect(parser.parseScript(script)).toEqual(['command2', 'command4']);
});
it('Throws if parsed scripts array is empty', () => {
const func = () => {
const script = `
# command1
# command2
`;
const result = parser.parseScript(script);
console.log(`Result: ${result}`);
};
expect(func).toThrowError(`No valid script found.`);
});
});
+3 -3
View File
@@ -16,9 +16,9 @@ inputs:
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`.'
emulator-options: headless:
description: 'command-line options used when launching the emulator - e.g. `-no-snapshot -camera-back emulated`.' description: 'whether to launch emulator in without UI - true or false'
default: '-no-window -no-snapshot -noaudio -no-boot-anim' default: 'true'
disable-animations: disable-animations:
description: 'whether to disable animations - true or false' description: 'whether to disable animations - true or false'
default: 'true' default: 'true'
+7 -13
View File
@@ -22,7 +22,7 @@ const ADB_PATH = `${process.env.ANDROID_HOME}/platform-tools/adb`;
/** /**
* 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, emulatorOptions, disableAnimations) { function launchEmulator(apiLevel, target, arch, profile, headless, disableAnimations) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// create a new AVD // create a new AVD
if (profile.trim() !== '') { if (profile.trim() !== '') {
@@ -35,15 +35,8 @@ function launchEmulator(apiLevel, target, arch, profile, emulatorOptions, disabl
} }
// start emulator // start emulator
console.log('Starting emulator.'); console.log('Starting emulator.');
yield exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd test ${emulatorOptions} &"`, [], { const noWindow = headless ? '-no-window' : '';
listeners: { yield exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd test ${noWindow} -no-snapshot -noaudio -no-boot-anim &"`);
stderr: (data) => {
if (data.toString().includes('invalid command-line parameter')) {
throw new Error(data.toString());
}
}
}
});
// wait for emulator to complete booting // wait for emulator to complete booting
yield waitForDevice(); yield waitForDevice();
yield exec.exec(`${ADB_PATH} shell input keyevent 82`); yield exec.exec(`${ADB_PATH} shell input keyevent 82`);
@@ -66,7 +59,7 @@ function killEmulator() {
yield exec.exec(`${ADB_PATH} -s emulator-5554 emu kill`); yield exec.exec(`${ADB_PATH} -s emulator-5554 emu kill`);
} }
catch (error) { catch (error) {
console.log(error.message); console.log('No emulator running on port 5554');
} }
}); });
} }
@@ -76,6 +69,7 @@ exports.killEmulator = killEmulator;
*/ */
function waitForDevice() { function waitForDevice() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const adbPath = `${process.env.ANDROID_HOME}/platform-tools/adb`;
let booted = false; let booted = false;
let attempts = 0; let attempts = 0;
const retryInterval = 2; // retry every 2 seconds const retryInterval = 2; // retry every 2 seconds
@@ -83,7 +77,7 @@ function waitForDevice() {
while (!booted) { while (!booted) {
try { try {
let result = ''; let result = '';
yield exec.exec(`${ADB_PATH} shell getprop sys.boot_completed`, [], { yield exec.exec(`${adbPath} shell getprop sys.boot_completed`, [], {
listeners: { listeners: {
stdout: (data) => { stdout: (data) => {
result += data.toString(); result += data.toString();
@@ -97,7 +91,7 @@ function waitForDevice() {
} }
} }
catch (error) { catch (error) {
console.log(error.message); console.error(error.message);
} }
if (attempts < maxAttemps) { if (attempts < maxAttemps) {
yield delay(retryInterval * 1000); yield delay(retryInterval * 1000);
+6
View File
@@ -24,6 +24,12 @@ function checkArch(arch) {
} }
} }
exports.checkArch = checkArch; exports.checkArch = checkArch;
function checkHeadless(headless) {
if (headless !== 'true' && headless !== 'false') {
throw new Error(`Input for input.headless should be either 'true' or 'false'.`);
}
}
exports.checkHeadless = checkHeadless;
function checkDisableAnimations(disableAnimations) { function checkDisableAnimations(disableAnimations) {
if (disableAnimations !== 'true' && disableAnimations !== 'false') { if (disableAnimations !== 'true' && disableAnimations !== 'false') {
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'.`);
+14 -25
View File
@@ -20,7 +20,6 @@ const sdk_installer_1 = require("./sdk-installer");
const input_validator_1 = require("./input-validator"); const input_validator_1 = require("./input-validator");
const emulator_manager_1 = require("./emulator-manager"); const emulator_manager_1 = require("./emulator-manager");
const exec = __importStar(require("@actions/exec")); const exec = __importStar(require("@actions/exec"));
const script_parser_1 = require("./script-parser");
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
@@ -40,43 +39,33 @@ function run() {
// CPU architecture of the system image // CPU architecture of the system image
const arch = core.getInput('arch'); const arch = core.getInput('arch');
input_validator_1.checkArch(arch); input_validator_1.checkArch(arch);
console.log(`CPU architecture: ${arch}`); console.log(`CPI architecture: ${arch}`);
// Hardware profile used for creating the AVD // Hardware profile used for creating the AVD
const profile = core.getInput('profile'); const profile = core.getInput('profile');
console.log(`Hardware profile: ${profile}`); console.log(`Hardware profile: ${profile}`);
// emulator options // headless mode
const emulatorOptions = core.getInput('emulator-options').trim(); const headlessInput = core.getInput('headless');
console.log(`emulator options: ${emulatorOptions}`); input_validator_1.checkHeadless(headlessInput);
const headless = headlessInput === 'true';
console.log(`headless mode: ${headless}`);
// disable animations // disable animations
const disableAnimationsInput = core.getInput('disable-animations'); const disableAnimationsInput = core.getInput('disable-animations');
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}`);
// custom script to run // custom scrpt to run
const scriptInput = core.getInput('script', { required: true }); const script = core.getInput('script', { required: true });
const scripts = script_parser_1.parseScript(scriptInput); // install SDK
console.log(`Script:`); yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch);
scripts.forEach((script) => __awaiter(this, void 0, void 0, function* () { // launch an emulator
console.log(`${script}`); yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, headless, disableAnimations);
})); // execute the custom script
try { try {
// install SDK yield exec.exec(`${script}`);
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch);
// launch an emulator
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, emulatorOptions, disableAnimations);
} }
catch (error) { catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }
// execute the custom script
scripts.forEach((script) => __awaiter(this, void 0, void 0, function* () {
try {
yield exec.exec(`${script}`);
}
catch (error) {
core.setFailed(error.message);
}
}));
// finally kill the emulator // finally kill the emulator
yield emulator_manager_1.killEmulator(); yield emulator_manager_1.killEmulator();
} }
-19
View File
@@ -1,19 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Convert a (potentially multi-line) script to an array of single-line script(s).
*/
function parseScript(rawScript) {
const scripts = rawScript
.trim()
.split(/\r\n|\n|\r/)
.map((value) => value.trim())
.filter((value) => {
return !value.startsWith('#') && value.length > 0;
});
if (scripts.length == 0) {
throw new Error(`No valid script found.`);
}
return scripts;
}
exports.parseScript = parseScript;
+20 -45
View File
@@ -1,40 +1,14 @@
{ {
"_args": [ "name": "@actions/core",
[ "version": "1.0.0",
"@actions/core@1.0.0",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "@actions/core@1.0.0",
"_id": "@actions/core@1.0.0",
"_inBundle": false,
"_integrity": "sha512-aMIlkx96XH4E/2YZtEOeyrYQfhlas9jIRkfGPqMwXD095Rdkzo4lB6ZmbxPQSzD+e1M+Xsm98ZhuSMYGv/AlqA==",
"_location": "/@actions/core",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@actions/core@1.0.0",
"name": "@actions/core",
"escapedName": "@actions%2fcore",
"scope": "@actions",
"rawSpec": "1.0.0",
"saveSpec": null,
"fetchSpec": "1.0.0"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.0.0.tgz",
"_spec": "1.0.0",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"description": "Actions core lib", "description": "Actions core lib",
"devDependencies": { "keywords": [
"@types/node": "^12.0.2" "core",
}, "actions"
],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
"license": "MIT",
"main": "lib/core.js",
"directories": { "directories": {
"lib": "lib", "lib": "lib",
"test": "__tests__" "test": "__tests__"
@@ -42,15 +16,6 @@
"files": [ "files": [
"lib" "lib"
], ],
"gitHead": "a40bce7c8d382aa3dbadaa327acbc696e9390e55",
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
"keywords": [
"core",
"actions"
],
"license": "MIT",
"main": "lib/core.js",
"name": "@actions/core",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -62,5 +27,15 @@
"test": "echo \"Error: run tests from root\" && exit 1", "test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc" "tsc": "tsc"
}, },
"version": "1.0.0" "bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"devDependencies": {
"@types/node": "^12.0.2"
},
"gitHead": "a40bce7c8d382aa3dbadaa327acbc696e9390e55"
,"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.0.0.tgz"
,"_integrity": "sha512-aMIlkx96XH4E/2YZtEOeyrYQfhlas9jIRkfGPqMwXD095Rdkzo4lB6ZmbxPQSzD+e1M+Xsm98ZhuSMYGv/AlqA=="
,"_from": "@actions/core@1.0.0"
} }
+21 -47
View File
@@ -1,41 +1,15 @@
{ {
"_args": [ "name": "@actions/exec",
[ "version": "1.0.1",
"@actions/exec@1.0.1",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "@actions/exec@1.0.1",
"_id": "@actions/exec@1.0.1",
"_inBundle": false,
"_integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ==",
"_location": "/@actions/exec",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@actions/exec@1.0.1",
"name": "@actions/exec",
"escapedName": "@actions%2fexec",
"scope": "@actions",
"rawSpec": "1.0.1",
"saveSpec": null,
"fetchSpec": "1.0.1"
},
"_requiredBy": [
"/",
"/@actions/tool-cache"
],
"_resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.1.tgz",
"_spec": "1.0.1",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"description": "Actions exec lib", "description": "Actions exec lib",
"devDependencies": { "keywords": [
"@actions/io": "^1.0.1" "github",
}, "actions",
"exec"
],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"license": "MIT",
"main": "lib/exec.js",
"directories": { "directories": {
"lib": "lib", "lib": "lib",
"test": "__tests__" "test": "__tests__"
@@ -43,16 +17,6 @@
"files": [ "files": [
"lib" "lib"
], ],
"gitHead": "a2ab4bcf78e4f7080f0d45856e6eeba16f0bbc52",
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"keywords": [
"github",
"actions",
"exec"
],
"license": "MIT",
"main": "lib/exec.js",
"name": "@actions/exec",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -64,5 +28,15 @@
"test": "echo \"Error: run tests from root\" && exit 1", "test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc" "tsc": "tsc"
}, },
"version": "1.0.1" "bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"devDependencies": {
"@actions/io": "^1.0.1"
},
"gitHead": "a2ab4bcf78e4f7080f0d45856e6eeba16f0bbc52"
,"_resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.1.tgz"
,"_integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ=="
,"_from": "@actions/exec@1.0.1"
} }
+18 -43
View File
@@ -1,37 +1,15 @@
{ {
"_args": [ "name": "@actions/io",
[ "version": "1.0.1",
"@actions/io@1.0.1",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "@actions/io@1.0.1",
"_id": "@actions/io@1.0.1",
"_inBundle": false,
"_integrity": "sha512-rhq+tfZukbtaus7xyUtwKfuiCRXd1hWSfmJNEpFgBQJ4woqPEpsBw04awicjwz9tyG2/MVhAEMfVn664Cri5zA==",
"_location": "/@actions/io",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@actions/io@1.0.1",
"name": "@actions/io",
"escapedName": "@actions%2fio",
"scope": "@actions",
"rawSpec": "1.0.1",
"saveSpec": null,
"fetchSpec": "1.0.1"
},
"_requiredBy": [
"/@actions/tool-cache"
],
"_resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.1.tgz",
"_spec": "1.0.1",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"description": "Actions io lib", "description": "Actions io lib",
"keywords": [
"github",
"actions",
"io"
],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/io",
"license": "MIT",
"main": "lib/io.js",
"directories": { "directories": {
"lib": "lib", "lib": "lib",
"test": "__tests__" "test": "__tests__"
@@ -39,16 +17,6 @@
"files": [ "files": [
"lib" "lib"
], ],
"gitHead": "a2ab4bcf78e4f7080f0d45856e6eeba16f0bbc52",
"homepage": "https://github.com/actions/toolkit/tree/master/packages/io",
"keywords": [
"github",
"actions",
"io"
],
"license": "MIT",
"main": "lib/io.js",
"name": "@actions/io",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -60,5 +28,12 @@
"test": "echo \"Error: run tests from root\" && exit 1", "test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc" "tsc": "tsc"
}, },
"version": "1.0.1" "bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"gitHead": "a2ab4bcf78e4f7080f0d45856e6eeba16f0bbc52"
,"_resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.1.tgz"
,"_integrity": "sha512-rhq+tfZukbtaus7xyUtwKfuiCRXd1hWSfmJNEpFgBQJ4woqPEpsBw04awicjwz9tyG2/MVhAEMfVn664Cri5zA=="
,"_from": "@actions/io@1.0.1"
} }
+20 -45
View File
@@ -1,40 +1,15 @@
{ {
"_args": [ "name": "@actions/core",
[ "version": "1.2.0",
"@actions/core@1.2.0",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "@actions/core@1.2.0",
"_id": "@actions/core@1.2.0",
"_inBundle": false,
"_integrity": "sha512-ZKdyhlSlyz38S6YFfPnyNgCDZuAF2T0Qv5eHflNWytPS8Qjvz39bZFMry9Bb/dpSnqWcNeav5yM2CTYpJeY+Dw==",
"_location": "/@actions/tool-cache/@actions/core",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@actions/core@1.2.0",
"name": "@actions/core",
"escapedName": "@actions%2fcore",
"scope": "@actions",
"rawSpec": "1.2.0",
"saveSpec": null,
"fetchSpec": "1.2.0"
},
"_requiredBy": [
"/@actions/tool-cache"
],
"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.0.tgz",
"_spec": "1.2.0",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"description": "Actions core lib", "description": "Actions core lib",
"devDependencies": { "keywords": [
"@types/node": "^12.0.2" "github",
}, "actions",
"core"
],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
"license": "MIT",
"main": "lib/core.js",
"directories": { "directories": {
"lib": "lib", "lib": "lib",
"test": "__tests__" "test": "__tests__"
@@ -42,15 +17,6 @@
"files": [ "files": [
"lib" "lib"
], ],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
"keywords": [
"github",
"actions",
"core"
],
"license": "MIT",
"main": "lib/core.js",
"name": "@actions/core",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -63,5 +29,14 @@
"test": "echo \"Error: run tests from root\" && exit 1", "test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc" "tsc": "tsc"
}, },
"version": "1.2.0" "bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"devDependencies": {
"@types/node": "^12.0.2"
}
,"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.0.tgz"
,"_integrity": "sha512-ZKdyhlSlyz38S6YFfPnyNgCDZuAF2T0Qv5eHflNWytPS8Qjvz39bZFMry9Bb/dpSnqWcNeav5yM2CTYpJeY+Dw=="
,"_from": "@actions/core@1.2.0"
} }
+31 -56
View File
@@ -1,51 +1,15 @@
{ {
"_args": [ "name": "@actions/tool-cache",
[ "version": "1.1.2",
"@actions/tool-cache@1.1.2",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "@actions/tool-cache@1.1.2",
"_id": "@actions/tool-cache@1.1.2",
"_inBundle": false,
"_integrity": "sha512-IJczPaZr02ECa3Lgws/TJEVco9tjOujiQSZbO3dHuXXjhd5vrUtfOgGwhmz3/f97L910OraPZ8SknofUk6RvOQ==",
"_location": "/@actions/tool-cache",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@actions/tool-cache@1.1.2",
"name": "@actions/tool-cache",
"escapedName": "@actions%2ftool-cache",
"scope": "@actions",
"rawSpec": "1.1.2",
"saveSpec": null,
"fetchSpec": "1.1.2"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.1.2.tgz",
"_spec": "1.1.2",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"dependencies": {
"@actions/core": "^1.1.0",
"@actions/exec": "^1.0.1",
"@actions/io": "^1.0.1",
"semver": "^6.1.0",
"typed-rest-client": "^1.4.0",
"uuid": "^3.3.2"
},
"description": "Actions tool-cache lib", "description": "Actions tool-cache lib",
"devDependencies": { "keywords": [
"@types/nock": "^10.0.3", "github",
"@types/semver": "^6.0.0", "actions",
"@types/uuid": "^3.4.4", "exec"
"nock": "^10.0.6" ],
}, "homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"license": "MIT",
"main": "lib/tool-cache.js",
"directories": { "directories": {
"lib": "lib", "lib": "lib",
"test": "__tests__" "test": "__tests__"
@@ -54,15 +18,6 @@
"lib", "lib",
"scripts" "scripts"
], ],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"keywords": [
"github",
"actions",
"exec"
],
"license": "MIT",
"main": "lib/tool-cache.js",
"name": "@actions/tool-cache",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -74,5 +29,25 @@
"test": "echo \"Error: run tests from root\" && exit 1", "test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc" "tsc": "tsc"
}, },
"version": "1.1.2" "bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"dependencies": {
"@actions/core": "^1.1.0",
"@actions/exec": "^1.0.1",
"@actions/io": "^1.0.1",
"semver": "^6.1.0",
"typed-rest-client": "^1.4.0",
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/nock": "^10.0.3",
"@types/semver": "^6.0.0",
"@types/uuid": "^3.4.4",
"nock": "^10.0.6"
}
,"_resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.1.2.tgz"
,"_integrity": "sha512-IJczPaZr02ECa3Lgws/TJEVco9tjOujiQSZbO3dHuXXjhd5vrUtfOgGwhmz3/f97L910OraPZ8SknofUk6RvOQ=="
,"_from": "@actions/tool-cache@1.1.2"
} }
+19 -53
View File
@@ -1,66 +1,32 @@
{ {
"_args": [ "name": "semver",
[ "version": "6.3.0",
"semver@6.3.0",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "semver@6.3.0",
"_id": "semver@6.3.0",
"_inBundle": false,
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"_location": "/semver",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "semver@6.3.0",
"name": "semver",
"escapedName": "semver",
"rawSpec": "6.3.0",
"saveSpec": null,
"fetchSpec": "6.3.0"
},
"_requiredBy": [
"/@actions/tool-cache",
"/@typescript-eslint/typescript-estree",
"/eslint",
"/istanbul-lib-instrument"
],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_spec": "6.3.0",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bin": {
"semver": "./bin/semver.js"
},
"bugs": {
"url": "https://github.com/npm/node-semver/issues"
},
"description": "The semantic version parser used by npm.", "description": "The semantic version parser used by npm.",
"main": "semver.js",
"scripts": {
"test": "tap",
"preversion": "npm test",
"postversion": "npm publish",
"postpublish": "git push origin --follow-tags"
},
"devDependencies": { "devDependencies": {
"tap": "^14.3.1" "tap": "^14.3.1"
}, },
"license": "ISC",
"repository": "https://github.com/npm/node-semver",
"bin": {
"semver": "./bin/semver.js"
},
"files": [ "files": [
"bin", "bin",
"range.bnf", "range.bnf",
"semver.js" "semver.js"
], ],
"homepage": "https://github.com/npm/node-semver#readme",
"license": "ISC",
"main": "semver.js",
"name": "semver",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/node-semver.git"
},
"scripts": {
"postpublish": "git push origin --follow-tags",
"postversion": "npm publish",
"preversion": "npm test",
"test": "tap"
},
"tap": { "tap": {
"check-coverage": true "check-coverage": true
}, }
"version": "6.3.0"
,"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
,"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
,"_from": "semver@6.3.0"
} }
+20 -49
View File
@@ -1,51 +1,7 @@
{ {
"_args": [ "name": "tunnel",
[ "version": "0.0.4",
"tunnel@0.0.4",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "tunnel@0.0.4",
"_id": "tunnel@0.0.4",
"_inBundle": false,
"_integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=",
"_location": "/tunnel",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "tunnel@0.0.4",
"name": "tunnel",
"escapedName": "tunnel",
"rawSpec": "0.0.4",
"saveSpec": null,
"fetchSpec": "0.0.4"
},
"_requiredBy": [
"/typed-rest-client"
],
"_resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz",
"_spec": "0.0.4",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"author": {
"name": "Koichi Kobayashi",
"email": "koichik@improvement.jp"
},
"bugs": {
"url": "https://github.com/koichik/node-tunnel/issues"
},
"description": "Node HTTP/HTTPS Agents for tunneling proxies", "description": "Node HTTP/HTTPS Agents for tunneling proxies",
"devDependencies": {
"mocha": "*",
"should": "*"
},
"directories": {
"lib": "./lib"
},
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
},
"homepage": "https://github.com/koichik/node-tunnel/",
"keywords": [ "keywords": [
"http", "http",
"https", "https",
@@ -53,15 +9,30 @@
"proxy", "proxy",
"tunnel" "tunnel"
], ],
"homepage": "https://github.com/koichik/node-tunnel/",
"bugs": "https://github.com/koichik/node-tunnel/issues",
"license": "MIT", "license": "MIT",
"author": "Koichi Kobayashi <koichik@improvement.jp>",
"main": "./index.js", "main": "./index.js",
"name": "tunnel", "directories": {
"lib": "./lib"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/koichik/node-tunnel.git" "url": "https://github.com/koichik/node-tunnel.git"
}, },
"scripts": { "scripts": {
"test": "./node_modules/mocha/bin/mocha" "test": "./node_modules/mocha/bin/mocha"
}, },
"version": "0.0.4" "devDependencies": {
"mocha": "*",
"should": "*"
},
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
,"_resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz"
,"_integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM="
,"_from": "tunnel@0.0.4"
} }
+36 -62
View File
@@ -1,55 +1,20 @@
{ {
"_args": [ "name": "typed-rest-client",
[ "version": "1.5.0",
"typed-rest-client@1.5.0",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "typed-rest-client@1.5.0",
"_id": "typed-rest-client@1.5.0",
"_inBundle": false,
"_integrity": "sha512-DVZRlmsfnTjp6ZJaatcdyvvwYwbWvR4YDNFDqb+qdTxpvaVP99YCpBkA8rxsLtAPjBVoDe4fNsnMIdZTiPuKWg==",
"_location": "/typed-rest-client",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "typed-rest-client@1.5.0",
"name": "typed-rest-client",
"escapedName": "typed-rest-client",
"rawSpec": "1.5.0",
"saveSpec": null,
"fetchSpec": "1.5.0"
},
"_requiredBy": [
"/@actions/tool-cache"
],
"_resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.5.0.tgz",
"_spec": "1.5.0",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"author": {
"name": "Microsoft Corporation"
},
"bugs": {
"url": "https://github.com/Microsoft/typed-rest-client/issues"
},
"dependencies": {
"tunnel": "0.0.4",
"underscore": "1.8.3"
},
"description": "Node Rest and Http Clients for use with TypeScript", "description": "Node Rest and Http Clients for use with TypeScript",
"devDependencies": { "main": "./RestClient.js",
"@types/mocha": "^2.2.44", "scripts": {
"@types/node": "^6.0.92", "build": "node make.js build",
"@types/shelljs": "0.7.4", "test": "node make.js test",
"mocha": "^3.5.3", "bt": "node make.js buildtest",
"nock": "9.6.1", "samples": "node make.js samples",
"react-scripts": "1.1.5", "units": "node make.js units",
"semver": "4.3.3", "validate": "node make.js validate"
"shelljs": "0.7.6", },
"typescript": "3.1.5" "repository": {
"type": "git",
"url": "git+https://github.com/Microsoft/typed-rest-client.git"
}, },
"homepage": "https://github.com/Microsoft/typed-rest-client#readme",
"keywords": [ "keywords": [
"rest", "rest",
"http", "http",
@@ -57,20 +22,29 @@
"typescript", "typescript",
"node" "node"
], ],
"author": "Microsoft Corporation",
"license": "MIT", "license": "MIT",
"main": "./RestClient.js", "bugs": {
"name": "typed-rest-client", "url": "https://github.com/Microsoft/typed-rest-client/issues"
"repository": {
"type": "git",
"url": "git+https://github.com/Microsoft/typed-rest-client.git"
}, },
"scripts": { "homepage": "https://github.com/Microsoft/typed-rest-client#readme",
"bt": "node make.js buildtest", "devDependencies": {
"build": "node make.js build", "@types/mocha": "^2.2.44",
"samples": "node make.js samples", "@types/node": "^6.0.92",
"test": "node make.js test", "@types/shelljs": "0.7.4",
"units": "node make.js units", "mocha": "^3.5.3",
"validate": "node make.js validate" "nock": "9.6.1",
"react-scripts": "1.1.5",
"shelljs": "0.7.6",
"semver": "4.3.3",
"typescript": "3.1.5"
}, },
"version": "1.5.0" "dependencies": {
"tunnel": "0.0.4",
"underscore": "1.8.3"
}
,"_resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.5.0.tgz"
,"_integrity": "sha512-DVZRlmsfnTjp6ZJaatcdyvvwYwbWvR4YDNFDqb+qdTxpvaVP99YCpBkA8rxsLtAPjBVoDe4fNsnMIdZTiPuKWg=="
,"_from": "typed-rest-client@1.5.0"
} }
+30 -60
View File
@@ -1,54 +1,6 @@
{ {
"_args": [ "name": "underscore",
[
"underscore@1.8.3",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "underscore@1.8.3",
"_id": "underscore@1.8.3",
"_inBundle": false,
"_integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
"_location": "/underscore",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "underscore@1.8.3",
"name": "underscore",
"escapedName": "underscore",
"rawSpec": "1.8.3",
"saveSpec": null,
"fetchSpec": "1.8.3"
},
"_requiredBy": [
"/typed-rest-client"
],
"_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"_spec": "1.8.3",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"author": {
"name": "Jeremy Ashkenas",
"email": "jeremy@documentcloud.org"
},
"bugs": {
"url": "https://github.com/jashkenas/underscore/issues"
},
"description": "JavaScript's functional programming helper library.", "description": "JavaScript's functional programming helper library.",
"devDependencies": {
"docco": "*",
"eslint": "0.6.x",
"karma": "~0.12.31",
"karma-qunit": "~0.1.4",
"qunit-cli": "~0.2.0",
"uglify-js": "2.4.x"
},
"files": [
"underscore.js",
"underscore-min.js",
"underscore-min.map",
"LICENSE"
],
"homepage": "http://underscorejs.org", "homepage": "http://underscorejs.org",
"keywords": [ "keywords": [
"util", "util",
@@ -57,20 +9,38 @@
"client", "client",
"browser" "browser"
], ],
"license": "MIT", "author": "Jeremy Ashkenas <jeremy@documentcloud.org>",
"main": "underscore.js",
"name": "underscore",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/jashkenas/underscore.git" "url": "git://github.com/jashkenas/underscore.git"
}, },
"scripts": { "main": "underscore.js",
"build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js", "version": "1.8.3",
"doc": "docco underscore.js", "devDependencies": {
"lint": "eslint underscore.js test/*.js", "docco": "*",
"test": "npm run test-node && npm run lint", "eslint": "0.6.x",
"test-browser": "npm i karma-phantomjs-launcher && ./node_modules/karma/bin/karma start", "karma": "~0.12.31",
"test-node": "qunit-cli test/*.js" "karma-qunit": "~0.1.4",
"qunit-cli": "~0.2.0",
"uglify-js": "2.4.x"
}, },
"version": "1.8.3" "scripts": {
"test": "npm run test-node && npm run lint",
"lint": "eslint underscore.js test/*.js",
"test-node": "qunit-cli test/*.js",
"test-browser": "npm i karma-phantomjs-launcher && ./node_modules/karma/bin/karma start",
"build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js",
"doc": "docco underscore.js"
},
"license": "MIT",
"files": [
"underscore.js",
"underscore-min.js",
"underscore-min.map",
"LICENSE"
]
,"_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz"
,"_integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
,"_from": "underscore@1.8.3"
} }
+26 -77
View File
@@ -1,72 +1,21 @@
{ {
"_args": [ "name": "uuid",
[ "version": "3.3.2",
"uuid@3.3.2", "description": "RFC4122 (v1, v4, and v5) UUIDs",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "uuid@3.3.2",
"_id": "uuid@3.3.2",
"_inBundle": false,
"_integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"_location": "/uuid",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "uuid@3.3.2",
"name": "uuid",
"escapedName": "uuid",
"rawSpec": "3.3.2",
"saveSpec": null,
"fetchSpec": "3.3.2"
},
"_requiredBy": [
"/@actions/tool-cache",
"/request"
],
"_resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"_spec": "3.3.2",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"bin": {
"uuid": "./bin/uuid"
},
"browser": {
"./lib/rng.js": "./lib/rng-browser.js",
"./lib/sha1.js": "./lib/sha1-browser.js",
"./lib/md5.js": "./lib/md5-browser.js"
},
"bugs": {
"url": "https://github.com/kelektiv/node-uuid/issues"
},
"commitlint": { "commitlint": {
"extends": [ "extends": [
"@commitlint/config-conventional" "@commitlint/config-conventional"
] ]
}, },
"contributors": [ "keywords": [
{ "uuid",
"name": "Robert Kieffer", "guid",
"email": "robert@broofa.com" "rfc4122"
},
{
"name": "Christoph Tavan",
"email": "dev@tavan.de"
},
{
"name": "AJ ONeal",
"email": "coolaj86@gmail.com"
},
{
"name": "Vincent Voyer",
"email": "vincent@zeroload.net"
},
{
"name": "Roman Shtylman",
"email": "shtylman@gmail.com"
}
], ],
"description": "RFC4122 (v1, v4, and v5) UUIDs", "license": "MIT",
"bin": {
"uuid": "./bin/uuid"
},
"devDependencies": { "devDependencies": {
"@commitlint/cli": "7.0.0", "@commitlint/cli": "7.0.0",
"@commitlint/config-conventional": "7.0.1", "@commitlint/config-conventional": "7.0.1",
@@ -76,24 +25,24 @@
"runmd": "1.0.1", "runmd": "1.0.1",
"standard-version": "4.4.0" "standard-version": "4.4.0"
}, },
"homepage": "https://github.com/kelektiv/node-uuid#readme",
"keywords": [
"uuid",
"guid",
"rfc4122"
],
"license": "MIT",
"name": "uuid",
"repository": {
"type": "git",
"url": "git+https://github.com/kelektiv/node-uuid.git"
},
"scripts": { "scripts": {
"commitmsg": "commitlint -E GIT_PARAMS", "commitmsg": "commitlint -E GIT_PARAMS",
"test": "mocha test/test.js",
"md": "runmd --watch --output=README.md README_js.md", "md": "runmd --watch --output=README.md README_js.md",
"prepare": "runmd --output=README.md README_js.md",
"release": "standard-version", "release": "standard-version",
"test": "mocha test/test.js" "prepare": "runmd --output=README.md README_js.md"
}, },
"version": "3.3.2" "browser": {
"./lib/rng.js": "./lib/rng-browser.js",
"./lib/sha1.js": "./lib/sha1-browser.js",
"./lib/md5.js": "./lib/md5-browser.js"
},
"repository": {
"type": "git",
"url": "https://github.com/kelektiv/node-uuid.git"
}
,"_resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz"
,"_integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
,"_from": "uuid@3.3.2"
} }
+7 -13
View File
@@ -7,7 +7,7 @@ const ADB_PATH = `${process.env.ANDROID_HOME}/platform-tools/adb`;
/** /**
* Creates and launches a new AVD instance with the specified configurations. * Creates and launches a new AVD instance with the specified configurations.
*/ */
export async function launchEmulator(apiLevel: number, target: string, arch: string, profile: string, emulatorOptions: string, disableAnimations: boolean): Promise<void> { export async function launchEmulator(apiLevel: number, target: string, arch: string, profile: string, headless: boolean, disableAnimations: boolean): Promise<void> {
// create a new AVD // create a new AVD
if (profile.trim() !== '') { if (profile.trim() !== '') {
console.log(`Creating AVD with custom profile ${profile}`); console.log(`Creating AVD with custom profile ${profile}`);
@@ -19,15 +19,8 @@ export async function launchEmulator(apiLevel: number, target: string, arch: str
// start emulator // start emulator
console.log('Starting emulator.'); console.log('Starting emulator.');
await exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd test ${emulatorOptions} &"`, [], { const noWindow = headless ? '-no-window' : '';
listeners: { await exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd test ${noWindow} -no-snapshot -noaudio -no-boot-anim &"`);
stderr: (data: Buffer) => {
if (data.toString().includes('invalid command-line parameter')) {
throw new Error(data.toString());
}
}
}
});
// wait for emulator to complete booting // wait for emulator to complete booting
await waitForDevice(); await waitForDevice();
@@ -49,7 +42,7 @@ export async function killEmulator(): Promise<void> {
try { try {
await exec.exec(`${ADB_PATH} -s emulator-5554 emu kill`); await exec.exec(`${ADB_PATH} -s emulator-5554 emu kill`);
} catch (error) { } catch (error) {
console.log(error.message); console.log('No emulator running on port 5554');
} }
} }
@@ -57,6 +50,7 @@ export async function killEmulator(): Promise<void> {
* Wait for emulator to boot. * Wait for emulator to boot.
*/ */
async function waitForDevice(): Promise<void> { async function waitForDevice(): Promise<void> {
const adbPath = `${process.env.ANDROID_HOME}/platform-tools/adb`;
let booted = false; let booted = false;
let attempts = 0; let attempts = 0;
const retryInterval = 2; // retry every 2 seconds const retryInterval = 2; // retry every 2 seconds
@@ -64,7 +58,7 @@ async function waitForDevice(): Promise<void> {
while (!booted) { while (!booted) {
try { try {
let result = ''; let result = '';
await exec.exec(`${ADB_PATH} shell getprop sys.boot_completed`, [], { await exec.exec(`${adbPath} shell getprop sys.boot_completed`, [], {
listeners: { listeners: {
stdout: (data: Buffer) => { stdout: (data: Buffer) => {
result += data.toString(); result += data.toString();
@@ -77,7 +71,7 @@ async function waitForDevice(): Promise<void> {
break; break;
} }
} catch (error) { } catch (error) {
console.log(error.message); console.error(error.message);
} }
if (attempts < maxAttemps) { if (attempts < maxAttemps) {
+6
View File
@@ -23,6 +23,12 @@ export function checkArch(arch: string): void {
} }
} }
export function checkHeadless(headless: string): void {
if (headless !== 'true' && headless !== 'false') {
throw new Error(`Input for input.headless should be either 'true' or 'false'.`);
}
}
export function checkDisableAnimations(disableAnimations: string): void { export function checkDisableAnimations(disableAnimations: string): void {
if (disableAnimations !== 'true' && disableAnimations !== 'false') { if (disableAnimations !== 'true' && disableAnimations !== 'false') {
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'.`);
+17 -27
View File
@@ -1,9 +1,8 @@
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 } from './input-validator'; import { checkApiLevel, checkTarget, checkArch, checkHeadless, checkDisableAnimations } 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';
async function run() { async function run() {
try { try {
@@ -26,15 +25,17 @@ async function run() {
// CPU architecture of the system image // CPU architecture of the system image
const arch = core.getInput('arch'); const arch = core.getInput('arch');
checkArch(arch); checkArch(arch);
console.log(`CPU architecture: ${arch}`); console.log(`CPI architecture: ${arch}`);
// Hardware profile used for creating the AVD // Hardware profile used for creating the AVD
const profile = core.getInput('profile'); const profile = core.getInput('profile');
console.log(`Hardware profile: ${profile}`); console.log(`Hardware profile: ${profile}`);
// emulator options // headless mode
const emulatorOptions = core.getInput('emulator-options').trim(); const headlessInput = core.getInput('headless');
console.log(`emulator options: ${emulatorOptions}`); checkHeadless(headlessInput);
const headless = headlessInput === 'true';
console.log(`headless mode: ${headless}`);
// disable animations // disable animations
const disableAnimationsInput = core.getInput('disable-animations'); const disableAnimationsInput = core.getInput('disable-animations');
@@ -42,33 +43,22 @@ async function run() {
const disableAnimations = disableAnimationsInput === 'true'; const disableAnimations = disableAnimationsInput === 'true';
console.log(`disable animations: ${disableAnimations}`); console.log(`disable animations: ${disableAnimations}`);
// custom script to run // custom scrpt to run
const scriptInput = core.getInput('script', { required: true }); const script = core.getInput('script', { required: true });
const scripts = parseScript(scriptInput);
console.log(`Script:`);
scripts.forEach(async (script: string) => {
console.log(`${script}`);
});
// install SDK
await installAndroidSdk(apiLevel, target, arch);
// launch an emulator
await launchEmulator(apiLevel, target, arch, profile, headless, disableAnimations);
// execute the custom script
try { try {
// install SDK await exec.exec(`${script}`);
await installAndroidSdk(apiLevel, target, arch);
// launch an emulator
await launchEmulator(apiLevel, target, arch, profile, emulatorOptions, disableAnimations);
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }
// execute the custom script
scripts.forEach(async (script: string) => {
try {
await exec.exec(`${script}`);
} catch (error) {
core.setFailed(error.message);
}
});
// finally kill the emulator // finally kill the emulator
await killEmulator(); await killEmulator();
} catch (error) { } catch (error) {
-18
View File
@@ -1,18 +0,0 @@
/**
* Convert a (potentially multi-line) script to an array of single-line script(s).
*/
export function parseScript(rawScript: string): Array<string> {
const scripts: Array<string> = rawScript
.trim()
.split(/\r\n|\n|\r/)
.map((value: string) => value.trim())
.filter((value: string) => {
return !value.startsWith('#') && value.length > 0;
});
if (scripts.length == 0) {
throw new Error(`No valid script found.`);
}
return scripts;
}