mirror of
https://github.com/reactivecircus/android-emulator-runner.git
synced 2026-09-01 10:09:33 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b2ebf2e51 | |||
| d203cdc3fb | |||
| 8896ab3615 | |||
| 8f0c30aea2 | |||
| d1f5d2c017 | |||
| d0dfd56912 | |||
| 7f2c89a896 | |||
| 1424075cfd | |||
| 0bc3ba22b5 | |||
| acdb69812b | |||
| f71c6d1f84 | |||
| 511d462729 | |||
| d83fb3d4fb | |||
| 1427331a62 | |||
| 1ded27b164 | |||
| 217e44e3c5 | |||
| 31d8d4204a | |||
| a5bc682448 | |||
| 4d1a61ed38 | |||
| 1bf9f17bc6 | |||
| 5de26e4bd2 | |||
| 5e487dbdfe | |||
| 08852ad83b | |||
| 25bcfbab74 | |||
| ac874f3db5 | |||
| 0c3db9cd7a | |||
| eba1fbfb59 | |||
| 6e775ef330 | |||
| 8a4333421e | |||
| 50ef0172a3 |
@@ -1,6 +1,8 @@
|
||||
name: Main workflow
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@@ -18,6 +20,7 @@ jobs:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
api-level: [16, 23, 29]
|
||||
target: [default, google_apis]
|
||||
arch: [x86]
|
||||
exclude:
|
||||
- os: ubuntu-latest
|
||||
api-level: 23
|
||||
@@ -30,15 +33,18 @@ jobs:
|
||||
- target: google_apis
|
||||
api-level: 29
|
||||
include:
|
||||
- os: macos-11.0
|
||||
api-level: 30
|
||||
target: google_apis
|
||||
- os: macos-latest
|
||||
api-level: 24
|
||||
target: playstore
|
||||
arch: x86
|
||||
- os: macos-latest
|
||||
api-level: 28
|
||||
api-level: 30
|
||||
target: aosp_atd
|
||||
arch: x86
|
||||
- os: macos-11
|
||||
api-level: 31
|
||||
target: google_apis
|
||||
arch: x86_64
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
@@ -84,7 +90,7 @@ jobs:
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ matrix.target }}
|
||||
arch: x86
|
||||
arch: ${{ matrix.arch }}
|
||||
profile: Galaxy Nexus
|
||||
cores: 2
|
||||
sdcard-path-or-size: 100M
|
||||
@@ -93,6 +99,7 @@ jobs:
|
||||
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: false
|
||||
working-directory: ./test-fixture/
|
||||
channel: canary
|
||||
script: echo "Generated AVD snapshot for caching."
|
||||
|
||||
- name: run action
|
||||
@@ -100,15 +107,17 @@ jobs:
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ matrix.target }}
|
||||
arch: x86
|
||||
arch: ${{ matrix.arch }}
|
||||
profile: Galaxy Nexus
|
||||
cores: 2
|
||||
ram-size: 2048M
|
||||
sdcard-path-or-size: 100M
|
||||
avd-name: test
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
working-directory: ./test-fixture/
|
||||
channel: canary
|
||||
script: |
|
||||
echo $GITHUB_REPOSITORY
|
||||
adb devices
|
||||
@@ -0,0 +1,76 @@
|
||||
name: Manually triggered workflow
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
os:
|
||||
description: 'OS'
|
||||
required: true
|
||||
default: 'macos-latest'
|
||||
api-level:
|
||||
description: 'API level of the platform and system image'
|
||||
required: true
|
||||
default: '30'
|
||||
target:
|
||||
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv or google-tv'
|
||||
required: true
|
||||
default: 'default'
|
||||
arch:
|
||||
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
||||
default: 'x86'
|
||||
emulator-options:
|
||||
description: 'command-line options used when launching the emulator'
|
||||
default: '-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim'
|
||||
emulator-build:
|
||||
description: 'build number of a specific version of the emulator binary to use'
|
||||
channel:
|
||||
description: 'Channel to download the SDK components from - `stable`, `beta`, `dev`, `canary`'
|
||||
default: 'stable'
|
||||
script:
|
||||
description: 'custom script to run - e.g. `./gradlew connectedCheck`'
|
||||
required: true
|
||||
default: './gradlew connectedDebugAndroidTest'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ github.event.inputs.os }}
|
||||
env:
|
||||
JAVA_TOOL_OPTIONS: -Xmx4g
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: validate gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: build, test and lint
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
npm run lint
|
||||
npm test
|
||||
|
||||
- name: Java 15
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 15
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
|
||||
|
||||
- name: run action
|
||||
uses: ./
|
||||
with:
|
||||
api-level: ${{ github.event.inputs.api-level }}
|
||||
target: ${{ github.event.inputs.target }}
|
||||
arch: ${{ github.event.inputs.arch }}
|
||||
profile: Galaxy Nexus
|
||||
emulator-options: ${{ github.event.inputs.emulator-options }}
|
||||
emulator-build: ${{ github.event.inputs.emulator-build }}
|
||||
channel: ${{ github.event.inputs.channel }}
|
||||
working-directory: ./test-fixture/
|
||||
script: ${{ github.event.inputs.script }}
|
||||
@@ -1,5 +1,32 @@
|
||||
# Change Log
|
||||
|
||||
## v2.21.0
|
||||
|
||||
* Support new [ATD](https://developer.android.com/studio/preview/features#gmd-atd) targets optimized to reduce CPU and memory resources when running instrumented tests: `aosp_atd`, `google_atd`. - [#198](https://github.com/ReactiveCircus/android-emulator-runner/pull/198). Note that currently these targets require the following:
|
||||
* `api-level: 30`
|
||||
* `arch: x86` or `arch: arm64-v8a`
|
||||
* `channel: canary`
|
||||
|
||||
## v2.20.0
|
||||
|
||||
* Support non-mobile targets: `android-wear`, `android-wear-cn`, `android-tv` and `google-tv`. - [#180](https://github.com/ReactiveCircus/android-emulator-runner/pull/180) @alexvanyo.
|
||||
* Update SDK command-line tools to `5.0`. - [#174](https://github.com/ReactiveCircus/android-emulator-runner/pull/174)
|
||||
* Update build tools to `31.0.0`. - [#174](https://github.com/ReactiveCircus/android-emulator-runner/pull/174)
|
||||
* Add option to specify the `channel` to download SDK components from: `stable` (default), `beta`, `dev` and `canary`. - [#185](https://github.com/ReactiveCircus/android-emulator-runner/pull/185)
|
||||
|
||||
## v2.19.1
|
||||
|
||||
* Accept all Android SDK Licenses to fix `sdkmanager` installation. - [#172](https://github.com/ReactiveCircus/android-emulator-runner/pull/172) @marcuspridham.
|
||||
|
||||
## v2.19.0
|
||||
|
||||
* Add option to specify `ram-size` for the AVD. - [#165](https://github.com/ReactiveCircus/android-emulator-runner/pull/165).
|
||||
|
||||
|
||||
## v2.18.1
|
||||
|
||||
* Added support for setting modern emulator build ids for `emulator-build`. Not all build ids are supported until we are able to figure out at which build id the download URL pattern changed. `7425822` (version 30.7.3) is currently the last known working build id.
|
||||
|
||||
## v2.18.0
|
||||
|
||||
* Add `force-avd-creation` which when set to `false` will skip avd creation if avd with same name exists. This enables AVD snapshot caching which can significantly reduce emulator startup time. See [README.md](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/README.md#usage) for a sample workflow. - [#159](https://github.com/ReactiveCircus/android-emulator-runner/pull/159)
|
||||
|
||||
@@ -147,6 +147,7 @@ jobs:
|
||||
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86`, `x86_64` or `arm64-v8a`. Note that `x86_64` image is only available for API 21+. `arm64-v8a` images require Android 4.2+ and are limited to fewer API levels (e.g. 30). |
|
||||
| `profile` | Optional | N/A | Hardware profile used for creating the AVD - e.g. `Nexus 6`. For a list of all profiles available, run `avdmanager list` and refer to the results under "Available Android Virtual Devices". |
|
||||
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
||||
| `ram-size` | Optional | N/A | Size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M` |
|
||||
| `sdcard-path-or-size` | Optional | N/A | Path to the SD card image for this AVD or the size of a new SD card image to create for this AVD, in KB or MB, denoted with K or M. - e.g. `path/to/sdcard`, or `1000M`. |
|
||||
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
|
||||
| `force-avd-creation` | Optional | `true` | Whether to force create the AVD by overwriting an existing AVD with the same name as `avd-name` - `true` or `false`. |
|
||||
@@ -158,6 +159,7 @@ jobs:
|
||||
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. |
|
||||
| `ndk` | Optional | N/A | Version of NDK to install - e.g. `21.0.6113669` |
|
||||
| `cmake` | Optional | N/A | Version of CMake to install - e.g. `3.10.2.4988404` |
|
||||
| `channel` | Optional | stable | Channel to download the SDK components from - `stable`, `beta`, `dev`, `canary` |
|
||||
| `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 -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim`.
|
||||
@@ -199,5 +201,8 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
|
||||
- [wikimedia/apps-android-wikipedia](https://github.com/wikimedia/apps-android-wikipedia/blob/master/.github/workflows)
|
||||
- [google/android-fhir](https://github.com/google/android-fhir/tree/master/.github/workflows)
|
||||
- [google/accompanist](https://github.com/google/accompanist/blob/main/.github/workflows)
|
||||
- [dotanuki-labs/norris](https://github.com/dotanuki-labs/norris/blob/master/.github/workflows/main.yml)
|
||||
- [tinylog-org/tinylog](https://github.com/tinylog-org/tinylog/blob/v3.0/.github/workflows/build.yaml)
|
||||
- [hzi-braunschweig/SORMAS-Project](https://github.com/hzi-braunschweig/SORMAS-Project/blob/development/.github/workflows/sormas_app_ci.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.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import * as mapper from '../src/channel-id-mapper';
|
||||
|
||||
describe('channel id mapper tests', () => {
|
||||
it('Throws if channelName is unknown', () => {
|
||||
const func = () => {
|
||||
mapper.getChannelId('unknown-channel');
|
||||
};
|
||||
expect(func).toThrowError(`Unexpected channel name: 'unknown-channel'.`);
|
||||
});
|
||||
|
||||
it('Returns expected channelId from channelName', () => {
|
||||
expect(mapper.getChannelId('stable')).toBe(0);
|
||||
expect(mapper.getChannelId('beta')).toBe(1);
|
||||
expect(mapper.getChannelId('dev')).toBe(2);
|
||||
expect(mapper.getChannelId('canary')).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -55,9 +55,39 @@ describe('target validator tests', () => {
|
||||
expect(func2).not.toThrow();
|
||||
|
||||
const func3 = () => {
|
||||
validator.checkTarget('google_apis');
|
||||
validator.checkTarget('aosp_atd');
|
||||
};
|
||||
expect(func3).not.toThrow();
|
||||
|
||||
const func4 = () => {
|
||||
validator.checkTarget('google_atd');
|
||||
};
|
||||
expect(func4).not.toThrow();
|
||||
|
||||
const func5 = () => {
|
||||
validator.checkTarget('google_apis_playstore');
|
||||
};
|
||||
expect(func5).not.toThrow();
|
||||
|
||||
const func6 = () => {
|
||||
validator.checkTarget('android-wear');
|
||||
};
|
||||
expect(func6).not.toThrow();
|
||||
|
||||
const func7 = () => {
|
||||
validator.checkTarget('android-wear-cn');
|
||||
};
|
||||
expect(func7).not.toThrow();
|
||||
|
||||
const func8 = () => {
|
||||
validator.checkTarget('android-tv');
|
||||
};
|
||||
expect(func8).not.toThrow();
|
||||
|
||||
const func9 = () => {
|
||||
validator.checkTarget('google-tv');
|
||||
};
|
||||
expect(func9).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,6 +112,37 @@ describe('arch validator tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('channel validator tests', () => {
|
||||
it('Throws if channel is unknown', () => {
|
||||
const func = () => {
|
||||
validator.checkChannel('some-channel');
|
||||
};
|
||||
expect(func).toThrowError(`Value for input.channel 'some-channel' is unknown. Supported options: ${validator.VALID_CHANNELS}`);
|
||||
});
|
||||
|
||||
it('Validates successfully with valid channel', () => {
|
||||
const func1 = () => {
|
||||
validator.checkChannel('stable');
|
||||
};
|
||||
expect(func1).not.toThrow();
|
||||
|
||||
const func2 = () => {
|
||||
validator.checkChannel('beta');
|
||||
};
|
||||
expect(func2).not.toThrow();
|
||||
|
||||
const func3 = () => {
|
||||
validator.checkChannel('dev');
|
||||
};
|
||||
expect(func3).not.toThrow();
|
||||
|
||||
const func4 = () => {
|
||||
validator.checkChannel('canary');
|
||||
};
|
||||
expect(func4).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('force-avd-creation validator tests', () => {
|
||||
it('Throws if force-avd-creation is not a boolean', () => {
|
||||
const func = () => {
|
||||
|
||||
+6
-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, google_apis or playstore'
|
||||
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv or google-tv'
|
||||
default: 'default'
|
||||
arch:
|
||||
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
||||
@@ -19,6 +19,8 @@ inputs:
|
||||
cores:
|
||||
description: 'the number of cores to use for the emulator'
|
||||
default: 2
|
||||
ram-size:
|
||||
description: 'size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M`'
|
||||
sdcard-path-or-size:
|
||||
description: 'path to the SD card image for this AVD or the size of a new SD card image to create for this AVD, in KB or MB, denoted with K or M. - e.g. `path/to/sdcard`, or `1000M`'
|
||||
avd-name:
|
||||
@@ -47,6 +49,9 @@ inputs:
|
||||
description: 'version of NDK to install - e.g. 21.0.6113669'
|
||||
cmake:
|
||||
description: 'version of CMake to install - e.g. 3.10.2.4988404'
|
||||
channel:
|
||||
description: 'Channel to download the SDK components from - `stable`, `beta`, `dev`, `canary`'
|
||||
default: 'stable'
|
||||
script:
|
||||
description: 'custom script to run - e.g. `./gradlew connectedCheck`'
|
||||
required: true
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getChannelId = void 0;
|
||||
function getChannelId(channelName) {
|
||||
if (channelName === 'stable') {
|
||||
return 0;
|
||||
}
|
||||
else if (channelName === 'beta') {
|
||||
return 1;
|
||||
}
|
||||
else if (channelName === 'dev') {
|
||||
return 2;
|
||||
}
|
||||
else if (channelName === 'canary') {
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unexpected channel name: '${channelName}'.`);
|
||||
}
|
||||
}
|
||||
exports.getChannelId = getChannelId;
|
||||
@@ -35,7 +35,7 @@ const EMULATOR_BOOT_TIMEOUT_SECONDS = 600;
|
||||
/**
|
||||
* Creates and launches a new AVD instance with the specified configurations.
|
||||
*/
|
||||
function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration) {
|
||||
function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, sdcardPathOrSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true
|
||||
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
|
||||
@@ -48,6 +48,9 @@ function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize
|
||||
if (cores) {
|
||||
yield exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||
}
|
||||
if (ramSize) {
|
||||
yield exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||
}
|
||||
//turn off hardware acceleration on Linux
|
||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||
console.log('Disabling Linux hardware acceleration.');
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.checkEmulatorBuild = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkForceAvdCreation = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
|
||||
exports.checkEmulatorBuild = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
|
||||
exports.MIN_API_LEVEL = 15;
|
||||
exports.VALID_TARGETS = ['default', 'google_apis', 'google_apis_playstore'];
|
||||
exports.VALID_TARGETS = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
|
||||
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
|
||||
exports.VALID_CHANNELS = ['stable', 'beta', 'dev', 'canary'];
|
||||
function checkApiLevel(apiLevel) {
|
||||
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
||||
throw new Error(`Unexpected API level: '${apiLevel}'.`);
|
||||
@@ -25,6 +26,12 @@ function checkArch(arch) {
|
||||
}
|
||||
}
|
||||
exports.checkArch = checkArch;
|
||||
function checkChannel(channel) {
|
||||
if (!exports.VALID_CHANNELS.includes(channel)) {
|
||||
throw new Error(`Value for input.channel '${channel}' is unknown. Supported options: ${exports.VALID_CHANNELS}.`);
|
||||
}
|
||||
}
|
||||
exports.checkChannel = checkChannel;
|
||||
function checkForceAvdCreation(forceAvdCreation) {
|
||||
if (!isValidBoolean(forceAvdCreation)) {
|
||||
throw new Error(`Input for input.force-avd-creation should be either 'true' or 'false'.`);
|
||||
|
||||
+11
-2
@@ -34,6 +34,7 @@ const input_validator_1 = require("./input-validator");
|
||||
const emulator_manager_1 = require("./emulator-manager");
|
||||
const exec = __importStar(require("@actions/exec"));
|
||||
const script_parser_1 = require("./script-parser");
|
||||
const channel_id_mapper_1 = require("./channel-id-mapper");
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
@@ -66,6 +67,9 @@ function run() {
|
||||
// Number of cores to use for emulator
|
||||
const cores = core.getInput('cores');
|
||||
console.log(`Cores: ${cores}`);
|
||||
// RAM to use for AVD
|
||||
const ramSize = core.getInput('ram-size');
|
||||
console.log(`RAM size: ${ramSize}`);
|
||||
// SD card path or size used for creating the AVD
|
||||
const sdcardPathOrSize = core.getInput('sdcard-path-or-size');
|
||||
console.log(`SD card path or size: ${sdcardPathOrSize}`);
|
||||
@@ -120,6 +124,11 @@ function run() {
|
||||
console.log(`version of CMake to install: ${cmakeInput}`);
|
||||
}
|
||||
const cmakeVersion = !cmakeInput ? undefined : cmakeInput;
|
||||
// channelId (up to and including) to download the SDK packages from
|
||||
const channelName = core.getInput('channel');
|
||||
input_validator_1.checkChannel(channelName);
|
||||
const channelId = channel_id_mapper_1.getChannelId(channelName);
|
||||
console.log(`Channel: ${channelId} (${channelName})`);
|
||||
// custom script to run
|
||||
const scriptInput = core.getInput('script', { required: true });
|
||||
const scripts = script_parser_1.parseScript(scriptInput);
|
||||
@@ -128,9 +137,9 @@ function run() {
|
||||
console.log(`${script}`);
|
||||
}));
|
||||
// install SDK
|
||||
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
|
||||
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
||||
// launch an emulator
|
||||
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration);
|
||||
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, ramSize, sdcardPathOrSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration);
|
||||
// execute the custom script
|
||||
try {
|
||||
// move to custom working directory if set
|
||||
|
||||
+15
-27
@@ -34,14 +34,14 @@ 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.3';
|
||||
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';
|
||||
const BUILD_TOOLS_VERSION = '31.0.0';
|
||||
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-7583922_latest.zip';
|
||||
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-7583922_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.
|
||||
*/
|
||||
function installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion) {
|
||||
function installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const isOnMac = process.platform === 'darwin';
|
||||
if (!isOnMac) {
|
||||
@@ -59,42 +59,30 @@ function installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cm
|
||||
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_SDK_ROOT}/platform-tools`);
|
||||
// set standard AVD path
|
||||
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
|
||||
// additional permission and license requirements for Linux
|
||||
const sdkPreviewLicensePath = `${process.env.ANDROID_SDK_ROOT}/licenses/android-sdk-preview-license`;
|
||||
if (!isOnMac && !fs.existsSync(sdkPreviewLicensePath)) {
|
||||
fs.writeFileSync(sdkPreviewLicensePath, '\n84831b9409646a918e30573bab4c9c91346d8abd');
|
||||
}
|
||||
// license required for API 30 and non-default API 28 system images
|
||||
const sdkArmDbtLicensePath = `${process.env.ANDROID_SDK_ROOT}/licenses/android-sdk-arm-dbt-license`;
|
||||
if (requiresArmDbtLicense(apiLevel, target) && !fs.existsSync(sdkArmDbtLicensePath)) {
|
||||
fs.writeFileSync(sdkArmDbtLicensePath, '\n859f317696f67ef3d7f30a50a5560e7834b43903');
|
||||
}
|
||||
// accept all Android SDK licenses
|
||||
yield exec.exec(`sh -c \\"yes | sdkmanager --licenses > /dev/null"`);
|
||||
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"`);
|
||||
console.log('Installing latest emulator.');
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /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 io.rmRF(`${process.env.ANDROID_SDK_ROOT}/emulator`);
|
||||
yield exec.exec(`unzip -q emulator.zip -d ${process.env.ANDROID_SDK_ROOT}`);
|
||||
// TODO find out the correct download URLs for all build ids
|
||||
const downloadUrlSuffix = Number(emulatorBuild.charAt(0)) > 6 ? `_x64-${emulatorBuild}` : `-${emulatorBuild}`;
|
||||
yield exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}${downloadUrlSuffix}.zip`);
|
||||
yield exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_SDK_ROOT}`);
|
||||
yield io.rmRF('emulator.zip');
|
||||
}
|
||||
else {
|
||||
console.log('Installing latest emulator.');
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install emulator > /dev/null"`);
|
||||
}
|
||||
console.log('Installing system images.');
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' > /dev/null"`);
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
|
||||
if (ndkVersion) {
|
||||
console.log(`Installing NDK ${ndkVersion}.`);
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' > /dev/null"`);
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' --channel=${channelId} > /dev/null"`);
|
||||
}
|
||||
if (cmakeVersion) {
|
||||
console.log(`Installing CMake ${cmakeVersion}.`);
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' > /dev/null"`);
|
||||
yield exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' --channel=${channelId} > /dev/null"`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.installAndroidSdk = installAndroidSdk;
|
||||
function requiresArmDbtLicense(apiLevel, target) {
|
||||
return apiLevel === 30 || (apiLevel === 28 && target !== 'default');
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Generated
+463
-360
File diff suppressed because it is too large
Load Diff
+10
-9
@@ -21,24 +21,25 @@
|
||||
"author": "Reactive Circus",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/exec": "^1.0.4",
|
||||
"@actions/tool-cache": "^1.6.1",
|
||||
"minimist": "^1.2.5"
|
||||
"@actions/core": "^1.5.0",
|
||||
"@actions/exec": "^1.1.0",
|
||||
"@actions/tool-cache": "^1.7.1",
|
||||
"minimist": "^1.2.5",
|
||||
"set-value": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^24.9.1",
|
||||
"@types/node": "^12.19.11",
|
||||
"@types/node": "^12.20.25",
|
||||
"@typescript-eslint/eslint-plugin": "^2.34.0",
|
||||
"@typescript-eslint/parser": "^2.34.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-prettier": "^3.3.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-prettier": "^3.4.1",
|
||||
"jest": "^26.6.3",
|
||||
"jest-circus": "^25.5.4",
|
||||
"prettier": "^1.19.1",
|
||||
"ts-jest": "^26.4.4",
|
||||
"typescript": "^3.9.7"
|
||||
"ts-jest": "^26.5.6",
|
||||
"typescript": "^3.9.10"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export function getChannelId(channelName: string): number {
|
||||
if (channelName === 'stable') {
|
||||
return 0;
|
||||
} else if (channelName === 'beta') {
|
||||
return 1;
|
||||
} else if (channelName === 'dev') {
|
||||
return 2;
|
||||
} else if (channelName === 'canary') {
|
||||
return 3;
|
||||
} else {
|
||||
throw new Error(`Unexpected channel name: '${channelName}'.`);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ export async function launchEmulator(
|
||||
arch: string,
|
||||
profile: string,
|
||||
cores: string,
|
||||
ramSize: string,
|
||||
sdcardPathOrSize: string,
|
||||
avdName: string,
|
||||
forceAvdCreation: boolean,
|
||||
@@ -35,6 +36,10 @@ export async function launchEmulator(
|
||||
await exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||
}
|
||||
|
||||
if (ramSize) {
|
||||
await exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||
}
|
||||
|
||||
//turn off hardware acceleration on Linux
|
||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||
console.log('Disabling Linux hardware acceleration.');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export const MIN_API_LEVEL = 15;
|
||||
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'google_apis_playstore'];
|
||||
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
|
||||
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
|
||||
export const VALID_CHANNELS: Array<string> = ['stable', 'beta', 'dev', 'canary'];
|
||||
|
||||
export function checkApiLevel(apiLevel: string): void {
|
||||
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
||||
@@ -23,6 +24,12 @@ export function checkArch(arch: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function checkChannel(channel: string): void {
|
||||
if (!VALID_CHANNELS.includes(channel)) {
|
||||
throw new Error(`Value for input.channel '${channel}' is unknown. Supported options: ${VALID_CHANNELS}.`);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkForceAvdCreation(forceAvdCreation: string): void {
|
||||
if (!isValidBoolean(forceAvdCreation)) {
|
||||
throw new Error(`Input for input.force-avd-creation should be either 'true' or 'false'.`);
|
||||
|
||||
+15
-2
@@ -8,11 +8,13 @@ import {
|
||||
checkEmulatorBuild,
|
||||
checkDisableSpellchecker,
|
||||
checkDisableLinuxHardwareAcceleration,
|
||||
checkForceAvdCreation
|
||||
checkForceAvdCreation,
|
||||
checkChannel
|
||||
} from './input-validator';
|
||||
import { launchEmulator, killEmulator } from './emulator-manager';
|
||||
import * as exec from '@actions/exec';
|
||||
import { parseScript } from './script-parser';
|
||||
import { getChannelId } from './channel-id-mapper';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
@@ -52,6 +54,10 @@ async function run() {
|
||||
const cores = core.getInput('cores');
|
||||
console.log(`Cores: ${cores}`);
|
||||
|
||||
// RAM to use for AVD
|
||||
const ramSize = core.getInput('ram-size');
|
||||
console.log(`RAM size: ${ramSize}`);
|
||||
|
||||
// SD card path or size used for creating the AVD
|
||||
const sdcardPathOrSize = core.getInput('sdcard-path-or-size');
|
||||
console.log(`SD card path or size: ${sdcardPathOrSize}`);
|
||||
@@ -117,6 +123,12 @@ async function run() {
|
||||
}
|
||||
const cmakeVersion = !cmakeInput ? undefined : cmakeInput;
|
||||
|
||||
// channelId (up to and including) to download the SDK packages from
|
||||
const channelName = core.getInput('channel');
|
||||
checkChannel(channelName);
|
||||
const channelId = getChannelId(channelName);
|
||||
console.log(`Channel: ${channelId} (${channelName})`);
|
||||
|
||||
// custom script to run
|
||||
const scriptInput = core.getInput('script', { required: true });
|
||||
const scripts = parseScript(scriptInput);
|
||||
@@ -126,7 +138,7 @@ async function run() {
|
||||
});
|
||||
|
||||
// install SDK
|
||||
await installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
|
||||
await installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
||||
|
||||
// launch an emulator
|
||||
await launchEmulator(
|
||||
@@ -135,6 +147,7 @@ async function run() {
|
||||
arch,
|
||||
profile,
|
||||
cores,
|
||||
ramSize,
|
||||
sdcardPathOrSize,
|
||||
avdName,
|
||||
forceAvdCreation,
|
||||
|
||||
+17
-28
@@ -4,15 +4,15 @@ import * as io from '@actions/io';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const BUILD_TOOLS_VERSION = '30.0.3';
|
||||
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';
|
||||
const BUILD_TOOLS_VERSION = '31.0.0';
|
||||
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-7583922_latest.zip';
|
||||
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-7583922_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.
|
||||
*/
|
||||
export async function installAndroidSdk(apiLevel: number, target: string, arch: string, emulatorBuild?: string, ndkVersion?: string, cmakeVersion?: string): Promise<void> {
|
||||
export async function installAndroidSdk(apiLevel: number, target: string, arch: string, channelId: number, emulatorBuild?: string, ndkVersion?: string, cmakeVersion?: string): Promise<void> {
|
||||
const isOnMac = process.platform === 'darwin';
|
||||
|
||||
if (!isOnMac) {
|
||||
@@ -34,44 +34,33 @@ export async function installAndroidSdk(apiLevel: number, target: string, arch:
|
||||
// set standard AVD path
|
||||
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
|
||||
|
||||
// additional permission and license requirements for Linux
|
||||
const sdkPreviewLicensePath = `${process.env.ANDROID_SDK_ROOT}/licenses/android-sdk-preview-license`;
|
||||
if (!isOnMac && !fs.existsSync(sdkPreviewLicensePath)) {
|
||||
fs.writeFileSync(sdkPreviewLicensePath, '\n84831b9409646a918e30573bab4c9c91346d8abd');
|
||||
}
|
||||
|
||||
// license required for API 30 and non-default API 28 system images
|
||||
const sdkArmDbtLicensePath = `${process.env.ANDROID_SDK_ROOT}/licenses/android-sdk-arm-dbt-license`;
|
||||
if (requiresArmDbtLicense(apiLevel, target) && !fs.existsSync(sdkArmDbtLicensePath)) {
|
||||
fs.writeFileSync(sdkArmDbtLicensePath, '\n859f317696f67ef3d7f30a50a5560e7834b43903');
|
||||
}
|
||||
// accept all Android SDK licenses
|
||||
await exec.exec(`sh -c \\"yes | sdkmanager --licenses > /dev/null"`);
|
||||
|
||||
console.log('Installing latest build tools, platform tools, and platform.');
|
||||
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools 'platforms;android-${apiLevel}' > /dev/null"`);
|
||||
|
||||
console.log('Installing latest emulator.');
|
||||
await exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`);
|
||||
|
||||
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 io.rmRF(`${process.env.ANDROID_SDK_ROOT}/emulator`);
|
||||
await exec.exec(`unzip -q emulator.zip -d ${process.env.ANDROID_SDK_ROOT}`);
|
||||
// TODO find out the correct download URLs for all build ids
|
||||
const downloadUrlSuffix = Number(emulatorBuild.charAt(0)) > 6 ? `_x64-${emulatorBuild}` : `-${emulatorBuild}`;
|
||||
await exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}${downloadUrlSuffix}.zip`);
|
||||
await exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_SDK_ROOT}`);
|
||||
await io.rmRF('emulator.zip');
|
||||
} else {
|
||||
console.log('Installing latest emulator.');
|
||||
await exec.exec(`sh -c \\"sdkmanager --install emulator > /dev/null"`);
|
||||
}
|
||||
console.log('Installing system images.');
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' > /dev/null"`);
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
|
||||
|
||||
if (ndkVersion) {
|
||||
console.log(`Installing NDK ${ndkVersion}.`);
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' > /dev/null"`);
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' --channel=${channelId} > /dev/null"`);
|
||||
}
|
||||
if (cmakeVersion) {
|
||||
console.log(`Installing CMake ${cmakeVersion}.`);
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' > /dev/null"`);
|
||||
await exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' --channel=${channelId} > /dev/null"`);
|
||||
}
|
||||
}
|
||||
|
||||
function requiresArmDbtLicense(apiLevel: number, target: string): boolean {
|
||||
return apiLevel === 30 || (apiLevel === 28 && target !== 'default');
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion "31.0.0"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.testapp"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 30
|
||||
targetSdkVersion 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -26,10 +26,7 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'androidx.core:core-ktx:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
testImplementation 'junit:junit:4.13'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name="com.example.testapp.MainActivity">
|
||||
<activity
|
||||
android:name="com.example.testapp.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
@@ -10,9 +10,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
android:layout_gravity="center" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
@@ -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.5.10'
|
||||
ext.kotlin_version = '1.5.30'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.1'
|
||||
classpath 'com.android.tools.build:gradle:7.0.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
+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-7.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
|
||||
Reference in New Issue
Block a user