mirror of
https://github.com/reactivecircus/android-emulator-runner.git
synced 2026-09-01 18:19:32 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2196379783 | |||
| 448508a511 | |||
| fd437876c6 | |||
| 517fe314d7 | |||
| 4690ba2920 | |||
| 15da0b2f14 | |||
| 53151f5236 | |||
| fd240e46a6 | |||
| 04a32d7ac6 | |||
| 1eebfdbd84 | |||
| 47cc04b42b | |||
| dd0984ca1b | |||
| fef056dbdf | |||
| 31e4885c24 | |||
| a59d5e6807 | |||
| 8feb8a564a | |||
| d677dca18c | |||
| d23e781d9a | |||
| 29a8a60dbb | |||
| 327f6f1c1f | |||
| 1dc0441870 | |||
| fb3c06d709 | |||
| e22ecdedee |
@@ -3,36 +3,43 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# - 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
|
||||
@@ -42,32 +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
|
||||
- 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
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# 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).
|
||||
|
||||
@@ -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`. |
|
||||
@@ -129,5 +129,9 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
|
||||
- [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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
/**
|
||||
|
||||
@@ -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
@@ -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,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).
|
||||
*/
|
||||
|
||||
+37
-20
@@ -1,27 +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 io = __importStar(require("@actions/io"));
|
||||
const tc = __importStar(require("@actions/tool-cache"));
|
||||
const fs = __importStar(require("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,
|
||||
* and the system image for the chosen API level, CPU arch, and target.
|
||||
@@ -36,22 +51,24 @@ function installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cm
|
||||
if (!fs.existsSync(cmdlineToolsPath)) {
|
||||
console.log('Installing new cmdline-tools.');
|
||||
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
|
||||
yield io.mkdirP(`${process.env.ANDROID_HOME}/cmdline-tools`);
|
||||
yield exec.exec(`curl -fo commandlinetools.zip ${sdkUrl}`);
|
||||
yield exec.exec(`unzip -q commandlinetools.zip -d ${cmdlineToolsPath}`);
|
||||
yield io.rmRF('commandlinetools.zip');
|
||||
// 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}/tools:${cmdlineToolsPath}/tools/bin:${process.env.ANDROID_HOME}/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)) {
|
||||
yield exec.exec(`sh -c \\"echo -e '\n84831b9409646a918e30573bab4c9c91346d8abd' > ${sdkPreviewLicensePath}"`);
|
||||
fs.writeFileSync(sdkPreviewLicensePath, '\n84831b9409646a918e30573bab4c9c91346d8abd');
|
||||
}
|
||||
// license required for API 30 system images
|
||||
const sdkArmDbtLicensePath = `${process.env.ANDROID_HOME}/licenses/android-sdk-arm-dbt-license`;
|
||||
if (apiLevel == 30 && !fs.existsSync(sdkArmDbtLicensePath)) {
|
||||
yield exec.exec(`sh -c \\"echo -e '\n859f317696f67ef3d7f30a50a5560e7834b43903' > ${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"`);
|
||||
|
||||
Generated
+3302
-1417
File diff suppressed because it is too large
Load Diff
+16
-16
@@ -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,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
@@ -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}`);
|
||||
|
||||
|
||||
+15
-10
@@ -1,11 +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,
|
||||
@@ -22,25 +23,29 @@ export async function installAndroidSdk(apiLevel: number, target: string, arch:
|
||||
if (!fs.existsSync(cmdlineToolsPath)) {
|
||||
console.log('Installing new cmdline-tools.');
|
||||
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
|
||||
await io.mkdirP(`${process.env.ANDROID_HOME}/cmdline-tools`);
|
||||
await exec.exec(`curl -fo commandlinetools.zip ${sdkUrl}`);
|
||||
await exec.exec(`unzip -q commandlinetools.zip -d ${cmdlineToolsPath}`);
|
||||
await io.rmRF('commandlinetools.zip');
|
||||
// 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}/tools:${cmdlineToolsPath}/tools/bin:${process.env.ANDROID_HOME}/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)) {
|
||||
await exec.exec(`sh -c \\"echo -e '\n84831b9409646a918e30573bab4c9c91346d8abd' > ${sdkPreviewLicensePath}"`);
|
||||
fs.writeFileSync(sdkPreviewLicensePath, '\n84831b9409646a918e30573bab4c9c91346d8abd');
|
||||
}
|
||||
|
||||
// license required for API 30 system images
|
||||
const sdkArmDbtLicensePath = `${process.env.ANDROID_HOME}/licenses/android-sdk-arm-dbt-license`;
|
||||
if (apiLevel == 30 && !fs.existsSync(sdkArmDbtLicensePath)) {
|
||||
await exec.exec(`sh -c \\"echo -e '\n859f317696f67ef3d7f30a50a5560e7834b43903' > ${sdkArmDbtLicensePath}"`);
|
||||
fs.writeFileSync(sdkArmDbtLicensePath, '\n859f317696f67ef3d7f30a50a5560e7834b43903');
|
||||
}
|
||||
|
||||
console.log('Installing latest build tools, platform tools, and platform.');
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user