Compare commits

...

27 Commits

Author SHA1 Message Date
Yang 2196379783 Test API 23-30. 2020-10-30 20:52:34 +11:00
Yang 448508a511 don't fail fast. 2020-10-30 20:41:01 +11:00
Yang fd437876c6 Try API 23-29. 2020-10-30 20:34:44 +11:00
Yang 517fe314d7 WIP - Test sdcard. 2020-10-30 20:31:43 +11:00
Daniel Jette 4690ba2920 Add Shopify/android-testify to list of projects
Shopify/android-testify uses the Android Emulator Runner for GitHub Actions
2020-10-27 08:42:51 +11:00
Yang 15da0b2f14 Prepare for release 2.12.0. 2020-10-16 14:39:02 +11:00
Yang 53151f5236 Add support for using google_apis_playstore system images. 2020-10-16 14:32:01 +11:00
Adrián Nieto Rodríguez fd240e46a6 Fix README.md typo 2020-10-15 00:01:10 +11:00
Yang 04a32d7ac6 Prepare for release 2.11.1. 2020-10-08 12:20:45 +11:00
Yang 1eebfdbd84 Update npm packages. 2020-10-08 12:14:51 +11:00
dependabot[bot] 47cc04b42b Bump @actions/core from 1.2.4 to 1.2.6
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.4 to 1.2.6.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-02 03:38:16 +10:00
Yang dd0984ca1b Update to gradle 6.7-rc-1 for test fixture. Build with Java 15 on CI. 2020-09-20 18:50:55 +10:00
Yang fef056dbdf Improve GitHub Actions Gradle cache. 2020-09-03 14:55:52 +10:00
Yang 31e4885c24 Add square/radiography to adopter list 2020-09-02 13:05:03 +10:00
Yang a59d5e6807 Add cashapp/copper to adapter list 2020-08-16 19:13:51 +10:00
Yang 8feb8a564a SDK Build tools 30.0.2. 2020-08-15 15:00:23 +10:00
Yang d677dca18c Update fixture dependencies. 2020-08-15 00:01:17 +10:00
Yang d23e781d9a Gradle 6.6. 2020-08-11 10:34:30 +10:00
Vinay Shenoy 29a8a60dbb Update README.md
We use this action for running instrumented tests in CI. Thanks for the great work!
2020-07-28 22:24:22 +10:00
Yang 327f6f1c1f Update packages. 2020-07-18 19:43:39 +10:00
Yang 1dc0441870 Build tools 30.0.1. 2020-07-09 19:49:16 +10:00
Yang fb3c06d709 Use fs for writing licence files. 2020-07-03 16:14:01 +10:00
Yang e22ecdedee Update cmdline-tools to 2.1. 2020-06-24 23:39:11 +10:00
Yang a72b5eb6c0 Prepare for release 2.11.0. 2020-06-20 19:52:48 +10:00
Yang b39f1a9f8b Support running multiple actions sequentially in a single job. 2020-06-20 19:48:18 +10:00
Yang a4d07e10d7 Add RxBinding to adopter list. 2020-06-19 14:46:44 +10:00
Yang 6f6ca5ebc6 Rename master branch to main. 2020-06-18 19:26:07 +10:00
20 changed files with 3569 additions and 1554 deletions
+55 -33
View File
@@ -3,34 +3,43 @@ on:
pull_request:
push:
branches:
- master
# - main
- 'yc/*'
paths-ignore:
- '**.md'
jobs:
test:
runs-on: ${{ matrix.os }}
# runs-on: ${{ matrix.os }}
runs-on: macos-latest
env:
JAVA_TOOL_OPTIONS: -Xmx4g
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
api-level: [16, 23, 29]
target: [default, google_apis]
exclude:
- os: ubuntu-latest
api-level: 23
- os: ubuntu-latest
api-level: 29
- target: google_apis
api-level: 16
- target: google_apis
api-level: 23
- target: google_apis
api-level: 29
include:
- os: macos-latest
api-level: 30
target: google_apis
# os: [macos-latest, ubuntu-latest]
api-level: [23, 24, 25, 26, 27, 28, 29, 30]
# target: [default, google_apis]
# exclude:
# - os: ubuntu-latest
# api-level: 23
# - os: ubuntu-latest
# api-level: 29
# - target: google_apis
# api-level: 16
# - target: google_apis
# api-level: 23
# - target: google_apis
# api-level: 29
# include:
# - os: macos-latest
# api-level: 30
# target: google_apis
# - os: macos-latest
# api-level: 24
# target: playstore
steps:
- name: checkout
uses: actions/checkout@v2
@@ -40,35 +49,48 @@ jobs:
- name: build, test and lint
run: |
npm install
npm ci
npm run build
npm run lint
npm test
- name: Java 14
- name: Java 15
uses: actions/setup-java@v1
with:
java-version: 14
- name: Clean cache
if: matrix.os == 'macos-latest'
run: mv ~/.gradle/caches ~/.gradle/.invalid_caches
- uses: actions/cache@v1
java-version: 15
- uses: actions/cache@v2
with:
path: ~/.gradle/caches
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
- name: run action
uses: ./
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
target: default
arch: x86
profile: Nexus 6
avd-name: test
# profile: Nexus 6
profile: pixel_3a
# avd-name: test
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none
disable-animations: true
working-directory: ./test-fixture/
script: |
echo $GITHUB_REPOSITORY
adb devices
./gradlew help
./gradlew connectedDebugAndroidTest
adb shell ls -la /sdcard
adb shell ls -la /storage
adb emu geo fix 0 51
adb shell screenrecord --verbose /sdcard/capture.mpg &
adb shell pkill -INT screenrecord
mkdir -p app/build/report
cd app/build/report && adb pull /sdcard/capture.mpg
# ./gradlew help
# ./gradlew connectedDebugAndroidTest
- name: Upload build artifacts
uses: actions/upload-artifact@v1
with:
name: build-outputs
path: ./test-fixture/app/build/report
+23
View File
@@ -1,5 +1,28 @@
# Change Log
## v2.12.0
Added support for using the `playstore` system images:
```
- name: run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 30
target: playstore
arch: x86
script: ./gradlew connectedCheck
```
## v2.11.1
* Update SDK command-line tools to `2.1`.
* Update @actions/core to `1.2.6`.
## v2.11.0
* Support running multiple instances of the action sequentially in a single job - [#73](https://github.com/ReactiveCircus/android-emulator-runner/issues/73).
## v2.10.0
* Support Android 11 (API 30) system images.
+14 -9
View File
@@ -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 **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 **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.
This action automates the process by doing the following:
@@ -86,12 +86,12 @@ jobs:
## Configurations
| | **Required** | **Default** | **Description** |
|----------------------|--------------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Input** | **Required** | **Default** | **Description** |
|-|-|-|-|
| `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` or `google_apis`. |
| `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+. |
| `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 `avdmanager list` and refer to the results under "Available Android Virtual Devices". |
| `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`. |
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
@@ -116,17 +116,22 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
- [coil-kt/coil](https://github.com/coil-kt/coil/blob/master/.github/workflows/)
- [cashapp/sqldelight](https://github.com/cashapp/sqldelight/blob/master/.github/workflows/)
- [square/workflow](https://github.com/square/workflow/blob/master/.github/workflows/)
- [square/workflow](https://github.com/square/workflow/blob/main/.github/workflows/)
- [square/retrofit](https://github.com/square/retrofit/blob/master/.github/workflows/)
- [natario1/CameraView](https://github.com/natario1/CameraView/tree/master/.github/workflows)
- [natario1/Transcoder](https://github.com/natario1/Transcoder/tree/master/.github/workflows)
- [chrisbanes/insetter](https://github.com/chrisbanes/insetter/tree/master/.github/workflows)
- [slackhq/keeper](https://github.com/slackhq/keeper/tree/master/.github/workflows)
- [chrisbanes/insetter](https://github.com/chrisbanes/insetter/tree/main/.github/workflows)
- [slackhq/keeper](https://github.com/slackhq/keeper/tree/main/.github/workflows)
- [android/compose-samples](https://github.com/android/compose-samples/blob/master/.github/workflows/ci.yaml)
- [ReactiveCircus/streamlined](https://github.com/ReactiveCircus/streamlined/tree/master/.github/workflows)
- [ReactiveCircus/streamlined](https://github.com/ReactiveCircus/streamlined/tree/main/.github/workflows)
- [ReactiveCircus/FlowBinding](https://github.com/ReactiveCircus/FlowBinding)
- [JakeWharton/RxBinding](https://github.com/JakeWharton/RxBinding/tree/master/.github/workflows)
- [vinaygaba/Learn-Jetpack-Compose-By-Example](https://github.com/vinaygaba/Learn-Jetpack-Compose-By-Example/)
- [ashishb/adb-enhanced](https://github.com/ashishb/adb-enhanced/tree/master/.github/workflows)
- [vgaidarji/ci-matters](https://github.com/vgaidarji/ci-matters/blob/master/.github/workflows/main.yaml)
- [simpledotorg/simple-android](https://github.com/simpledotorg/simple-android)
- [cashapp/copper](https://github.com/cashapp/copper/blob/trunk/.github/workflows/build.yaml)
- [square/radiography](https://github.com/square/radiography/blob/main/.github/workflows/android.yml)
- [Shopify/android-testify](https://github.com/Shopify/android-testify/blob/master/.github/workflows/sample_build.yml)
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.
+3 -3
View File
@@ -4,7 +4,7 @@ Refer to the [recommendeations for versioning and releasing actions](https://git
## New major release
- From `master` branch, run `npm run build && npm test --clean && npm run lint` to make sure `lib/*.js` are up-to-date.
- From `main` branch, run `npm run build && npm test --clean && npm run lint` to make sure `lib/*.js` are up-to-date.
- Update `CHANGELOG.md`, push change with "Prepare for release X.Y.Z." (where X.Y.Z is the new version).
- Create a new branch e.g. `release/v1`, comment out `node_modules/` in `.gitignore`, commit the change (do not commit yet `node_modules`).
- Run `npm prune --production`.
@@ -17,9 +17,9 @@ Refer to the [recommendeations for versioning and releasing actions](https://git
## New minor / patch release
- From `master` branch, run `npm run build && npm test --clean && npm run lint` to make sure `lib/*.js` are up-to-date.
- From `main` branch, run `npm run build && npm test --clean && npm run lint` to make sure `lib/*.js` are up-to-date.
- Update `CHANGELOG.md`, push change with "Prepare for release X.Y.Z." (where X.Y.Z is the new version).
- Merge from `master` into the release branch e.g. `release/v1`.
- Merge from `main` into the release branch e.g. `release/v1`.
- Run `npm prune --production`.
- Commit merged changes (and the pruned `node_modules`).
- Push to remote.
+5
View File
@@ -53,6 +53,11 @@ describe('target validator tests', () => {
validator.checkTarget('google_apis');
};
expect(func2).not.toThrow();
const func3 = () => {
validator.checkTarget('google_apis');
};
expect(func3).not.toThrow();
});
});
+1 -1
View File
@@ -9,7 +9,7 @@ inputs:
description: 'API level of the platform and system image - e.g. 23 for Android Marshmallow, 29 for Android 10'
required: true
target:
description: 'target of the system image - default or google_apis'
description: 'target of the system image - default, google_apis or playstore'
default: 'default'
arch:
description: 'CPU architecture of the system image - x86 or x86_64'
+24 -10
View File
@@ -1,20 +1,34 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.killEmulator = exports.launchEmulator = void 0;
const exec = __importStar(require("@actions/exec"));
const EMULATOR_BOOT_TIMEOUT_SECONDS = 600;
/**
+2 -1
View File
@@ -1,7 +1,8 @@
"use strict";
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.MIN_API_LEVEL = 15;
exports.VALID_TARGETS = ['default', 'google_apis'];
exports.VALID_TARGETS = ['default', 'google_apis', 'google_apis_playstore'];
exports.VALID_ARCHS = ['x86', 'x86_64'];
function checkApiLevel(apiLevel) {
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
+25 -11
View File
@@ -1,19 +1,32 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const sdk_installer_1 = require("./sdk-installer");
@@ -39,7 +52,8 @@ function run() {
const apiLevel = Number(apiLevelInput);
console.log(`API level: ${apiLevel}`);
// target of the system image
const target = core.getInput('target');
const targetInput = core.getInput('target');
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
input_validator_1.checkTarget(target);
console.log(`target: ${target}`);
// CPU architecture of the system image
+1
View File
@@ -1,5 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseScript = void 0;
/**
* Convert a (potentially multi-line) script to an array of single-line script(s).
*/
+54 -28
View File
@@ -1,25 +1,42 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.installAndroidSdk = void 0;
const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec"));
const BUILD_TOOLS_VERSION = '30.0.0';
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-6514223_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-6514223_latest.zip';
const io = __importStar(require("@actions/io"));
const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs"));
const BUILD_TOOLS_VERSION = '30.0.2';
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-6858069_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip';
/**
* Installs & updates the Android SDK for the macOS platform, including SDK platform for the chosen API level, latest build tools, platform tools, Android Emulator,
* and the system image for the chosen API level, CPU arch, and target.
@@ -27,31 +44,40 @@ const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/comman
function installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion) {
return __awaiter(this, void 0, void 0, function* () {
const isOnMac = process.platform === 'darwin';
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
yield exec.exec(`sudo mkdir ${process.env.ANDROID_HOME}/cmdline-tools`);
yield exec.exec(`curl -fo commandlinetools.zip ${sdkUrl}`);
yield exec.exec(`sudo unzip -q commandlinetools.zip -d ${process.env.ANDROID_HOME}/cmdline-tools`);
yield exec.exec(`sudo rm -f commandlinetools.zip`);
// add paths for commandline-tools and platform-tools
core.addPath(`${process.env.ANDROID_HOME}/cmdline-tools/tools:${process.env.ANDROID_HOME}/cmdline-tools/tools/bin:${process.env.ANDROID_HOME}/platform-tools`);
// additional permission and license requirements for Linux
if (!isOnMac) {
yield exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_HOME} -R`);
yield exec.exec(`sh -c \\"echo -e '\n84831b9409646a918e30573bab4c9c91346d8abd' > ${process.env.ANDROID_HOME}/licenses/android-sdk-preview-license"`);
}
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
if (!fs.existsSync(cmdlineToolsPath)) {
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
// await io.mkdirP(cmdlineToolsPath);
const downloadPath = yield tc.downloadTool(sdkUrl);
yield tc.extractZip(downloadPath, cmdlineToolsPath);
yield io.mv(`${cmdlineToolsPath}/cmdline-tools`, `${cmdlineToolsPath}/latest`);
yield exec.exec(`ls -la ${cmdlineToolsPath}`);
// add paths for commandline-tools and platform-tools
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_HOME}/platform-tools`);
yield exec.exec(`ls -la ${cmdlineToolsPath}/latest`);
}
// additional permission and license requirements for Linux
const sdkPreviewLicensePath = `${process.env.ANDROID_HOME}/licenses/android-sdk-preview-license`;
if (!isOnMac && !fs.existsSync(sdkPreviewLicensePath)) {
fs.writeFileSync(sdkPreviewLicensePath, '\n84831b9409646a918e30573bab4c9c91346d8abd');
}
// license required for API 30 system images
if (apiLevel == 30) {
yield exec.exec(`sh -c \\"echo -e '\n859f317696f67ef3d7f30a50a5560e7834b43903' > ${process.env.ANDROID_HOME}/licenses/android-sdk-arm-dbt-license"`);
const sdkArmDbtLicensePath = `${process.env.ANDROID_HOME}/licenses/android-sdk-arm-dbt-license`;
if (apiLevel == 30 && !fs.existsSync(sdkArmDbtLicensePath)) {
fs.writeFileSync(sdkArmDbtLicensePath, '\n859f317696f67ef3d7f30a50a5560e7834b43903');
}
console.log('Installing latest build tools, platform tools, and platform.');
yield exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools 'platforms;android-${apiLevel}' > /dev/null"`);
if (emulatorBuild) {
console.log(`Installing emulator build ${emulatorBuild}.`);
yield exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}-${emulatorBuild}.zip`);
yield exec.exec(`sudo rm -rf ${process.env.ANDROID_HOME}/emulator`);
yield exec.exec(`sudo unzip -q emulator.zip -d ${process.env.ANDROID_HOME}`);
yield exec.exec(`sudo rm -f emulator.zip`);
yield io.rmRF(`${process.env.ANDROID_HOME}/emulator`);
yield exec.exec(`unzip -q emulator.zip -d ${process.env.ANDROID_HOME}`);
yield io.rmRF('emulator.zip');
}
else {
console.log('Installing latest emulator.');
+3302 -1417
View File
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -21,24 +21,24 @@
"author": "Reactive Circus",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.0.0",
"@actions/exec": "^1.0.1",
"@actions/tool-cache": "^1.1.2",
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.4",
"@actions/tool-cache": "^1.6.0",
"minimist": "^1.2.5"
},
"devDependencies": {
"@types/jest": "^24.0.13",
"@types/node": "^12.0.4",
"@typescript-eslint/eslint-plugin": "^2.6.1",
"@typescript-eslint/parser": "^2.6.1",
"eslint": "^6.6.0",
"eslint-config-prettier": "^6.5.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.1",
"jest": "^25.2.3",
"jest-circus": "^25.2.3",
"prettier": "^1.18.2",
"ts-jest": "^24.0.2",
"typescript": "^3.5.1"
"@types/jest": "^24.9.1",
"@types/node": "^12.12.64",
"@typescript-eslint/eslint-plugin": "^2.34.0",
"@typescript-eslint/parser": "^2.34.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^25.5.4",
"jest-circus": "^25.5.4",
"prettier": "^1.19.1",
"ts-jest": "^26.4.1",
"typescript": "^3.9.7"
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
export const MIN_API_LEVEL = 15;
export const VALID_TARGETS: Array<string> = ['default', 'google_apis'];
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'google_apis_playstore'];
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64'];
export function checkApiLevel(apiLevel: string): void {
+2 -1
View File
@@ -25,7 +25,8 @@ async function run() {
console.log(`API level: ${apiLevel}`);
// target of the system image
const target = core.getInput('target');
const targetInput = core.getInput('target');
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
checkTarget(target);
console.log(`target: ${target}`);
+36 -19
View File
@@ -1,9 +1,12 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import * as fs from 'fs';
const BUILD_TOOLS_VERSION = '30.0.0';
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-6514223_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-6514223_latest.zip';
const BUILD_TOOLS_VERSION = '30.0.2';
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-6858069_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip';
/**
* Installs & updates the Android SDK for the macOS platform, including SDK platform for the chosen API level, latest build tools, platform tools, Android Emulator,
@@ -11,24 +14,38 @@ const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/comman
*/
export async function installAndroidSdk(apiLevel: number, target: string, arch: string, emulatorBuild?: string, ndkVersion?: string, cmakeVersion?: string): Promise<void> {
const isOnMac = process.platform === 'darwin';
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
await exec.exec(`sudo mkdir ${process.env.ANDROID_HOME}/cmdline-tools`);
await exec.exec(`curl -fo commandlinetools.zip ${sdkUrl}`);
await exec.exec(`sudo unzip -q commandlinetools.zip -d ${process.env.ANDROID_HOME}/cmdline-tools`);
await exec.exec(`sudo rm -f commandlinetools.zip`);
// add paths for commandline-tools and platform-tools
core.addPath(`${process.env.ANDROID_HOME}/cmdline-tools/tools:${process.env.ANDROID_HOME}/cmdline-tools/tools/bin:${process.env.ANDROID_HOME}/platform-tools`);
// additional permission and license requirements for Linux
if (!isOnMac) {
await exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_HOME} -R`);
await exec.exec(`sh -c \\"echo -e '\n84831b9409646a918e30573bab4c9c91346d8abd' > ${process.env.ANDROID_HOME}/licenses/android-sdk-preview-license"`);
}
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
if (!fs.existsSync(cmdlineToolsPath)) {
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
// await io.mkdirP(cmdlineToolsPath);
const downloadPath = await tc.downloadTool(sdkUrl);
await tc.extractZip(downloadPath, cmdlineToolsPath);
await io.mv(`${cmdlineToolsPath}/cmdline-tools`, `${cmdlineToolsPath}/latest`);
await exec.exec(`ls -la ${cmdlineToolsPath}`);
// add paths for commandline-tools and platform-tools
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_HOME}/platform-tools`);
await exec.exec(`ls -la ${cmdlineToolsPath}/latest`);
}
// additional permission and license requirements for Linux
const sdkPreviewLicensePath = `${process.env.ANDROID_HOME}/licenses/android-sdk-preview-license`;
if (!isOnMac && !fs.existsSync(sdkPreviewLicensePath)) {
fs.writeFileSync(sdkPreviewLicensePath, '\n84831b9409646a918e30573bab4c9c91346d8abd');
}
// license required for API 30 system images
if (apiLevel == 30) {
await exec.exec(`sh -c \\"echo -e '\n859f317696f67ef3d7f30a50a5560e7834b43903' > ${process.env.ANDROID_HOME}/licenses/android-sdk-arm-dbt-license"`);
const sdkArmDbtLicensePath = `${process.env.ANDROID_HOME}/licenses/android-sdk-arm-dbt-license`;
if (apiLevel == 30 && !fs.existsSync(sdkArmDbtLicensePath)) {
fs.writeFileSync(sdkArmDbtLicensePath, '\n859f317696f67ef3d7f30a50a5560e7834b43903');
}
console.log('Installing latest build tools, platform tools, and platform.');
@@ -37,9 +54,9 @@ export async function installAndroidSdk(apiLevel: number, target: string, arch:
if (emulatorBuild) {
console.log(`Installing emulator build ${emulatorBuild}.`);
await exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}-${emulatorBuild}.zip`);
await exec.exec(`sudo rm -rf ${process.env.ANDROID_HOME}/emulator`);
await exec.exec(`sudo unzip -q emulator.zip -d ${process.env.ANDROID_HOME}`);
await exec.exec(`sudo rm -f emulator.zip`);
await io.rmRF(`${process.env.ANDROID_HOME}/emulator`);
await exec.exec(`unzip -q emulator.zip -d ${process.env.ANDROID_HOME}`);
await io.rmRF('emulator.zip');
} else {
console.log('Installing latest emulator.');
await exec.exec(`sh -c \\"sdkmanager --install emulator > /dev/null"`);
+1 -1
View File
@@ -4,7 +4,7 @@ apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.example.testapp"
+2 -2
View File
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.72'
ext.kotlin_version = '1.4.0'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
+1
View File
@@ -1,6 +1,7 @@
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.caching=true
org.gradle.vfs.watch=true
# Enable Kotlin incremental compilation
kotlin.incremental=true
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip