Compare commits

..

24 Commits

Author SHA1 Message Date
Yang b390b0e116 Merge branch 'main' into release/v2
* main:
  Prepare for release 2.25.0.
  Check in missing compiled js file.
  Auto detect hardware acceleration on Linux (#254)
  Build tools 33.0.0. Update test fixture dependencies.
  Update Kotlin and AGP in test-fixture.
  SDK command-line tools 7.0.
2022-07-12 18:48:20 +10:00
Yang 402c25e52e Prepare for release 2.25.0. 2022-07-12 18:43:26 +10:00
Yang cd41888947 Check in missing compiled js file. 2022-07-12 18:38:58 +10:00
notbigdata 7809d88d54 Auto detect hardware acceleration on Linux (#254) 2022-07-12 18:32:26 +10:00
Yang a9c993651c Build tools 33.0.0. Update test fixture dependencies. 2022-06-17 23:54:56 +10:00
Yang f1d9765a2a Update Kotlin and AGP in test-fixture. 2022-05-26 11:29:00 +10:00
Yang eb6b0c0524 SDK command-line tools 7.0. 2022-05-14 17:17:56 +10:00
Yang e790971012 Merge branch 'main' into release/v2
* main:
  Prepare for release 2.24.0.
  Add option to specify AVD heap size (#245)
  Gradle 7.4.2.
  Bump GH actions (#240)
  Bump minimist from 1.2.5 to 1.2.6 (#237)
  Update dependencies in test-fixture.
  Add more .gitignore rules (#231)
  Update README for using with gradle/gradle-build-action (#230)
2022-04-30 23:35:35 +10:00
Yang f30ff064b1 Prepare for release 2.24.0. 2022-04-30 23:20:42 +10:00
Tim Malseed cc3dd8cbef Add option to specify AVD heap size (#245) 2022-04-26 23:36:59 +10:00
Yang 689ee971a8 Gradle 7.4.2. 2022-04-16 01:29:20 +10:00
Goooler 4ea6abdd76 Bump GH actions (#240) 2022-04-07 00:43:35 +10:00
dependabot[bot] 280a99ecb8 Bump minimist from 1.2.5 to 1.2.6 (#237)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-07 00:26:40 +10:00
Yang aacab61b72 Update dependencies in test-fixture. 2022-03-04 16:36:46 +11:00
Goooler a24195edb9 Add more .gitignore rules (#231)
* Add more .gitignore rules

* Update .gitignore
2022-03-04 16:31:18 +11:00
Goooler 20da7eafac Update README for using with gradle/gradle-build-action (#230)
* Update README for using with gradle/gradle-build-action

* Code highlighting in README

* Add a step in the snippet
2022-03-04 16:31:00 +11:00
Yang 76c2bf6f95 Merge branch 'main' into release/v2
* main:
  Prepare for release 2.23.0.
  Add missing generated .js files.
  Add GHA commands to group logs (#224)
  wikimedia have likely renamed master -> main (#221)
  Allow increasing main storage size (sdcard is separate storage) (#219)
  Update to SDK command-line tools 6.0. (#213)
  Update build tools to 32.0.0. Update text-fixture compileSdkVersion and targetSdkVersion to 32. (#212)
2022-02-18 01:49:20 +11:00
Yang 08a23a6229 Prepare for release 2.23.0. 2022-02-18 01:48:36 +11:00
Yang 5bd7b4aaec Add missing generated .js files. 2022-02-18 01:35:48 +11:00
Michael Kaye 1e2ef7249a Add GHA commands to group logs (#224) 2022-02-17 20:03:29 +11:00
Michael Kaye 3045dbfaba wikimedia have likely renamed master -> main (#221) 2022-02-11 08:41:38 +11:00
Vilius Sutkus '89 4e0dd2c343 Allow increasing main storage size (sdcard is separate storage) (#219)
* Allow increasing disk size - Issue #184

* Fix checkDiskSize validator

* Fix lint errors

* Size modifier without a number is unacceptable

"G" is not the same as "1G"

* Implement checkDiskSize validator tests
2022-02-05 16:07:40 +11:00
Yang 62d97062b0 Update to SDK command-line tools 6.0. (#213) 2022-01-27 16:22:43 +11:00
Yang e35fd713f4 Update build tools to 32.0.0. Update text-fixture compileSdkVersion and targetSdkVersion to 32. (#212) 2022-01-26 11:26:11 +11:00
25 changed files with 493 additions and 297 deletions
+4 -3
View File
@@ -48,7 +48,7 @@ jobs:
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: validate gradle wrapper - name: validate gradle wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v1
@@ -61,10 +61,11 @@ jobs:
npm test npm test
- name: Java 15 - name: Java 15
uses: actions/setup-java@v1 uses: actions/setup-java@v3
with: with:
distribution: 'zulu'
java-version: 15 java-version: 15
- uses: actions/cache@v2 - uses: actions/cache@v3
id: avd-cache id: avd-cache
with: with:
path: | path: |
+4 -3
View File
@@ -39,7 +39,7 @@ jobs:
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: validate gradle wrapper - name: validate gradle wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v1
@@ -52,10 +52,11 @@ jobs:
npm test npm test
- name: Java 15 - name: Java 15
uses: actions/setup-java@v1 uses: actions/setup-java@v3
with: with:
distribution: 'zulu'
java-version: 15 java-version: 15
- uses: actions/cache@v2 - uses: actions/cache@v3
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
+10
View File
@@ -91,3 +91,13 @@ typings/
# DynamoDB Local files # DynamoDB Local files
.dynamodb/ .dynamodb/
# Mac
.DS_Store
# Vscode
.vscode
# IntelliJ IDEA
.idea
*.iml
+17
View File
@@ -1,5 +1,22 @@
# Change Log # Change Log
## v2.25.0
* Auto detect hardware acceleration on Linux. - [#254](https://github.com/ReactiveCircus/android-emulator-runner/pull/254) @notbigdata.
* Update build tools to `33.0.0`.
* Update SDK command-line tools to `7.0`.
## v2.24.0
* Add option to specify `heap-size` for the AVD. - [#245](https://github.com/ReactiveCircus/android-emulator-runner/pull/245) @timusus.
## v2.23.0
* Update build tools to `32.0.0`. - [#212](https://github.com/ReactiveCircus/android-emulator-runner/pull/212)
* Update SDK command-line tools to `6.0`. - [#213](https://github.com/ReactiveCircus/android-emulator-runner/pull/213)
* Add option to specify `disk-size` for the AVD. - [#219](https://github.com/ReactiveCircus/android-emulator-runner/pull/219) @ViliusSutkus89.
* Improve logging by grouping log lines. - [#224](https://github.com/ReactiveCircus/android-emulator-runner/pull/224) @michaelkaye.
## v2.22.0 ## v2.22.0
* Add option to enable hardware keyboard. - [#209](https://github.com/ReactiveCircus/android-emulator-runner/pull/209) (upstreamed from the [Doist fork](https://github.com/Doist/android-emulator-runner/commit/4b6ca99f0d657662beca3eb0c22d8e254fbd5b31)). * Add option to enable hardware keyboard. - [#209](https://github.com/ReactiveCircus/android-emulator-runner/pull/209) (upstreamed from the [Doist fork](https://github.com/Doist/android-emulator-runner/commit/4b6ca99f0d657662beca3eb0c22d8e254fbd5b31)).
+18 -20
View File
@@ -26,13 +26,13 @@ It is recommended to run this action on a **macOS** VM, e.g. `macos-latest`, `ma
A workflow that uses **android-emulator-runner** to run your instrumented tests on **API 29**: A workflow that uses **android-emulator-runner** to run your instrumented tests on **API 29**:
``` ```yml
jobs: jobs:
test: test:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: run tests - name: run tests
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
@@ -43,7 +43,7 @@ jobs:
We can also leverage GitHub Actions's build matrix to test across multiple configurations: We can also leverage GitHub Actions's build matrix to test across multiple configurations:
``` ```yml
jobs: jobs:
test: test:
runs-on: macos-latest runs-on: macos-latest
@@ -53,7 +53,7 @@ jobs:
target: [default, google_apis] target: [default, google_apis]
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: run tests - name: run tests
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
@@ -67,13 +67,13 @@ jobs:
If you need specific versions of **NDK** and **CMake** installed: If you need specific versions of **NDK** and **CMake** installed:
``` ```yml
jobs: jobs:
test: test:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: run tests - name: run tests
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
@@ -86,11 +86,12 @@ jobs:
We can significantly reduce emulator startup time by setting up AVD snapshot caching: We can significantly reduce emulator startup time by setting up AVD snapshot caching:
1. add an `actions/cache@v2` step for caching the `avd` 1. add a `gradle/gradle-build-action@v2` step for caching Gradle, more details see [#229](https://github.com/ReactiveCircus/android-emulator-runner/issues/229)
2. add a `reactivecircus/android-emulator-runner@v2` step to generate a clean snapshot - specify `emulator-options` without `no-snapshot` 2. add an `actions/cache@v3` step for caching the `avd`
3. add another `reactivecircus/android-emulator-runner@v2` step to run your tests using existing AVD / snapshot - specify `emulator-options` with `no-snapshot-save` 3. add a `reactivecircus/android-emulator-runner@v2` step to generate a clean snapshot - specify `emulator-options` without `no-snapshot`
4. add another `reactivecircus/android-emulator-runner@v2` step to run your tests using existing AVD / snapshot - specify `emulator-options` with `no-snapshot-save`
``` ```yml
jobs: jobs:
test: test:
runs-on: macos-latest runs-on: macos-latest
@@ -99,18 +100,13 @@ jobs:
api-level: [21, 23, 29] api-level: [21, 23, 29]
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Gradle cache - name: Gradle cache
uses: actions/cache@v2 uses: gradle/gradle-build-action@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }}
- name: AVD cache - name: AVD cache
uses: actions/cache@v2 uses: actions/cache@v3
id: avd-cache id: avd-cache
with: with:
path: | path: |
@@ -148,7 +144,9 @@ jobs:
| `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 device`. | | `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 device`. |
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). | | `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
| `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` | | `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` |
| `heap-size` | Optional | N/A | Heap size to use for this AVD, in KB or MB, denoted with K or M. - e.g. `512M` |
| `sdcard-path-or-size` | Optional | N/A | Path to the SD card image for this AVD or the size of a new SD card image to create for this AVD, in KB or MB, denoted with K or M. - e.g. `path/to/sdcard`, or `1000M`. | | `sdcard-path-or-size` | Optional | N/A | Path to the SD card image for this AVD or the size of a new SD card image to create for this AVD, in KB or MB, denoted with K or M. - e.g. `path/to/sdcard`, or `1000M`. |
| `disk-size` | Optional | N/A | Disk size to use for this AVD. Either in bytes or KB, MB or GB, when denoted with K, M or G. - e.g. `2048M` |
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. | | `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
| `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`. | | `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`. |
| `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-window -no-snapshot -camera-back emulated`. | | `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-window -no-snapshot -camera-back emulated`. |
@@ -199,7 +197,7 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
- [hash-checker/hash-checker](https://github.com/hash-checker/hash-checker/tree/master/.github/workflows) - [hash-checker/hash-checker](https://github.com/hash-checker/hash-checker/tree/master/.github/workflows)
- [hash-checker/hash-checker-lite](https://github.com/hash-checker/hash-checker-lite/tree/master/.github/workflows) - [hash-checker/hash-checker-lite](https://github.com/hash-checker/hash-checker-lite/tree/master/.github/workflows)
- [Kiwix/kiwix-android](https://github.com/kiwix/kiwix-android/blob/develop/.github/workflows) - [Kiwix/kiwix-android](https://github.com/kiwix/kiwix-android/blob/develop/.github/workflows)
- [wikimedia/apps-android-wikipedia](https://github.com/wikimedia/apps-android-wikipedia/blob/master/.github/workflows) - [wikimedia/apps-android-wikipedia](https://github.com/wikimedia/apps-android-wikipedia/blob/main/.github/workflows)
- [google/android-fhir](https://github.com/google/android-fhir/tree/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) - [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) - [dotanuki-labs/norris](https://github.com/dotanuki-labs/norris/blob/master/.github/workflows/main.yml)
+58 -2
View File
@@ -211,10 +211,10 @@ describe('disable-linux-hw-accel validator tests', () => {
const func = () => { const func = () => {
validator.checkDisableLinuxHardwareAcceleration('yes'); validator.checkDisableLinuxHardwareAcceleration('yes');
}; };
expect(func).toThrowError(`Input for input.disable-linux-hw-accel should be either 'true' or 'false'.`); expect(func).toThrowError(`Input for input.disable-linux-hw-accel should be either 'true' or 'false' or 'auto'.`);
}); });
it('Validates successfully if disable-linux-hw-accel is either true or false', () => { it('Validates successfully if disable-linux-hw-accel is either true or false or auto', () => {
const func1 = () => { const func1 = () => {
validator.checkDisableLinuxHardwareAcceleration('true'); validator.checkDisableLinuxHardwareAcceleration('true');
}; };
@@ -224,6 +224,11 @@ describe('disable-linux-hw-accel validator tests', () => {
validator.checkDisableLinuxHardwareAcceleration('false'); validator.checkDisableLinuxHardwareAcceleration('false');
}; };
expect(func2).not.toThrow(); expect(func2).not.toThrow();
const func3 = () => {
validator.checkDisableLinuxHardwareAcceleration('auto');
};
expect(func3).not.toThrow();
}); });
}); });
@@ -270,3 +275,54 @@ describe('emulator-build validator tests', () => {
expect(func).not.toThrow(); expect(func).not.toThrow();
}); });
}); });
describe('checkDiskSize validator tests', () => {
it('Empty size is acceptable, means default', () => {
const func = () => {
validator.checkDiskSize('');
};
expect(func).not.toThrow();
});
it('Numbers means bytes', () => {
expect(() => {
validator.checkDiskSize('8000000000');
}).not.toThrow();
});
it('Uppercase size modifier', () => {
expect(() => {
validator.checkDiskSize('8000000K');
}).not.toThrow();
expect(() => {
validator.checkDiskSize('8000M');
}).not.toThrow();
expect(() => {
validator.checkDiskSize('8G');
}).not.toThrow();
});
it('Lowercase size modifier', () => {
expect(() => {
validator.checkDiskSize('8000000k');
}).not.toThrow();
expect(() => {
validator.checkDiskSize('8000m');
}).not.toThrow();
expect(() => {
validator.checkDiskSize('8g');
}).not.toThrow();
});
it('Modifier without a number is unacceptable', () => {
expect(() => {
validator.checkDiskSize('G');
}).toThrowError(`Unexpected disk size: 'G'.`);
});
it('Double modifier is unacceptable', () => {
expect(() => {
validator.checkDiskSize('14gg');
}).toThrowError(`Unexpected disk size: '14gg'.`);
});
});
+6 -2
View File
@@ -21,8 +21,12 @@ inputs:
default: 2 default: 2
ram-size: ram-size:
description: 'size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M`' description: 'size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M`'
heap-size:
description: 'size of heap to use for this AVD in MB. - e.g. `512M`'
sdcard-path-or-size: 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`' 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`'
disk-size:
description: 'disk size to use for this AVD. Either in bytes or KB, MB or GB, when denoted with K, M or G'
avd-name: avd-name:
description: 'custom AVD name used for creating the Android Virtual Device' description: 'custom AVD name used for creating the Android Virtual Device'
default: 'test' default: 'test'
@@ -39,8 +43,8 @@ inputs:
description: 'whether to disable spellchecker - `true` or `false`' description: 'whether to disable spellchecker - `true` or `false`'
default: 'false' default: 'false'
disable-linux-hw-accel: disable-linux-hw-accel:
description: 'whether to disable hardware acceleration on Linux machines - `true` or `false`' description: 'whether to disable hardware acceleration on Linux machines - `true` or `false` or `auto`'
default: 'true' default: 'auto'
enable-hw-keyboard: enable-hw-keyboard:
description: 'whether to enable hardware keyboard - `true` or `false`.' description: 'whether to enable hardware keyboard - `true` or `false`.'
default: 'false' default: 'false'
+60 -44
View File
@@ -35,55 +35,67 @@ const EMULATOR_BOOT_TIMEOUT_SECONDS = 600;
/** /**
* Creates and launches a new AVD instance with the specified configurations. * Creates and launches a new AVD instance with the specified configurations.
*/ */
function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, sdcardPathOrSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) { function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true try {
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`; console.log(`::group::Launch Emulator`);
if (!fs.existsSync(avdPath) || forceAvdCreation) { // create a new AVD if AVD directory does not already exist or forceAvdCreation is true
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : ''; const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : ''; if (!fs.existsSync(avdPath) || forceAvdCreation) {
console.log(`Creating AVD.`); const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`); const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : '';
} console.log(`Creating AVD.`);
if (cores) { yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`);
yield exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`); }
} if (cores) {
if (ramSize) { yield exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
yield exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`); }
} if (ramSize) {
if (enableHardwareKeyboard) { yield exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
yield exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`); }
} if (heapSize) {
//turn off hardware acceleration on Linux yield exec.exec(`sh -c \\"printf 'hw.heapSize=${heapSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) { }
console.log('Disabling Linux hardware acceleration.'); if (enableHardwareKeyboard) {
emulatorOptions += ' -accel off'; yield exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
} }
// start emulator if (diskSize) {
console.log('Starting emulator.'); yield exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
yield exec.exec(`sh -c \\"${process.env.ANDROID_SDK_ROOT}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], { }
listeners: { //turn off hardware acceleration on Linux
stderr: (data) => { if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
if (data.toString().includes('invalid command-line parameter')) { console.log('Disabling Linux hardware acceleration.');
throw new Error(data.toString()); emulatorOptions += ' -accel off';
}
// start emulator
console.log('Starting emulator.');
yield exec.exec(`sh -c \\"${process.env.ANDROID_SDK_ROOT}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], {
listeners: {
stderr: (data) => {
if (data.toString().includes('invalid command-line parameter')) {
throw new Error(data.toString());
}
} }
} }
});
// wait for emulator to complete booting
yield waitForDevice();
yield exec.exec(`adb shell input keyevent 82`);
if (disableAnimations) {
console.log('Disabling animations.');
yield exec.exec(`adb shell settings put global window_animation_scale 0.0`);
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
}
if (disableSpellChecker) {
yield exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
}
if (enableHardwareKeyboard) {
yield exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
} }
});
// wait for emulator to complete booting
yield waitForDevice();
yield exec.exec(`adb shell input keyevent 82`);
if (disableAnimations) {
console.log('Disabling animations.');
yield exec.exec(`adb shell settings put global window_animation_scale 0.0`);
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
} }
if (disableSpellChecker) { finally {
yield exec.exec(`adb shell settings put secure spell_checker_enabled 0`); console.log(`::endgroup::`);
}
if (enableHardwareKeyboard) {
yield exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
} }
}); });
} }
@@ -94,11 +106,15 @@ exports.launchEmulator = launchEmulator;
function killEmulator() { function killEmulator() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
console.log(`::group::Terminate Emulator`);
yield exec.exec(`adb -s emulator-5554 emu kill`); yield exec.exec(`adb -s emulator-5554 emu kill`);
} }
catch (error) { catch (error) {
console.log(error.message); console.log(error.message);
} }
finally {
console.log(`::endgroup::`);
}
}); });
} }
exports.killEmulator = killEmulator; exports.killEmulator = killEmulator;
+20 -3
View File
@@ -1,6 +1,6 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = 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.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = 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.MIN_API_LEVEL = 15;
exports.VALID_TARGETS = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv']; 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_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
@@ -51,8 +51,8 @@ function checkDisableSpellchecker(disableSpellchecker) {
} }
exports.checkDisableSpellchecker = checkDisableSpellchecker; exports.checkDisableSpellchecker = checkDisableSpellchecker;
function checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAcceleration) { function checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAcceleration) {
if (!isValidBoolean(disableLinuxHardwareAcceleration)) { if (!(isValidBoolean(disableLinuxHardwareAcceleration) || disableLinuxHardwareAcceleration === 'auto')) {
throw new Error(`Input for input.disable-linux-hw-accel should be either 'true' or 'false'.`); throw new Error(`Input for input.disable-linux-hw-accel should be either 'true' or 'false' or 'auto'.`);
} }
} }
exports.checkDisableLinuxHardwareAcceleration = checkDisableLinuxHardwareAcceleration; exports.checkDisableLinuxHardwareAcceleration = checkDisableLinuxHardwareAcceleration;
@@ -71,3 +71,20 @@ exports.checkEmulatorBuild = checkEmulatorBuild;
function isValidBoolean(value) { function isValidBoolean(value) {
return value === 'true' || value === 'false'; return value === 'true' || value === 'false';
} }
function checkDiskSize(diskSize) {
// Disk size can be empty - the default value
if (diskSize) {
// Can also be number of bytes
if (isNaN(Number(diskSize)) || !Number.isInteger(Number(diskSize))) {
// Disk size can have a size multiplier at the end K, M or G
const diskSizeUpperCase = diskSize.toUpperCase();
if (diskSizeUpperCase.endsWith('K') || diskSizeUpperCase.endsWith('M') || diskSizeUpperCase.endsWith('G')) {
const diskSizeNoModifier = diskSize.slice(0, -1);
if (0 == diskSizeNoModifier.length || isNaN(Number(diskSizeNoModifier)) || !Number.isInteger(Number(diskSizeNoModifier))) {
throw new Error(`Unexpected disk size: '${diskSize}'.`);
}
}
}
}
}
exports.checkDiskSize = checkDiskSize;
+22 -3
View File
@@ -35,13 +35,22 @@ const emulator_manager_1 = require("./emulator-manager");
const exec = __importStar(require("@actions/exec")); const exec = __importStar(require("@actions/exec"));
const script_parser_1 = require("./script-parser"); const script_parser_1 = require("./script-parser");
const channel_id_mapper_1 = require("./channel-id-mapper"); const channel_id_mapper_1 = require("./channel-id-mapper");
const fs_1 = require("fs");
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
console.log(`::group::Configure emulator`);
let linuxSupportKVM = false;
// only support running on macOS or Linux // only support running on macOS or Linux
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
if (process.platform === 'linux') { if (process.platform === 'linux') {
console.warn(`You're running a Linux VM where hardware acceleration is not available. Please consider using a macOS VM instead to take advantage of native hardware acceleration support provided by HAXM.`); try {
fs_1.accessSync('/dev/kvm', fs_1.constants.R_OK | fs_1.constants.W_OK);
linuxSupportKVM = true;
}
catch (_a) {
console.warn(`You're running a Linux VM where hardware acceleration is not available. Please consider using a macOS VM instead to take advantage of native hardware acceleration support provided by HAXM.`);
}
} }
else { else {
throw new Error('Unsupported virtual machine: please use either macos or ubuntu VM.'); throw new Error('Unsupported virtual machine: please use either macos or ubuntu VM.');
@@ -70,9 +79,15 @@ function run() {
// RAM to use for AVD // RAM to use for AVD
const ramSize = core.getInput('ram-size'); const ramSize = core.getInput('ram-size');
console.log(`RAM size: ${ramSize}`); console.log(`RAM size: ${ramSize}`);
// Heap size to use for AVD
const heapSize = core.getInput('heap-size');
console.log(`Heap size: ${heapSize}`);
// SD card path or size used for creating the AVD // SD card path or size used for creating the AVD
const sdcardPathOrSize = core.getInput('sdcard-path-or-size'); const sdcardPathOrSize = core.getInput('sdcard-path-or-size');
console.log(`SD card path or size: ${sdcardPathOrSize}`); console.log(`SD card path or size: ${sdcardPathOrSize}`);
const diskSize = core.getInput('disk-size');
input_validator_1.checkDiskSize(diskSize);
console.log(`Disk size: ${diskSize}`);
// custom name used for creating the AVD // custom name used for creating the AVD
const avdName = core.getInput('avd-name'); const avdName = core.getInput('avd-name');
console.log(`AVD name: ${avdName}`); console.log(`AVD name: ${avdName}`);
@@ -95,8 +110,11 @@ function run() {
const disableSpellchecker = disableSpellcheckerInput === 'true'; const disableSpellchecker = disableSpellcheckerInput === 'true';
console.log(`disable spellchecker: ${disableSpellchecker}`); console.log(`disable spellchecker: ${disableSpellchecker}`);
// disable linux hardware acceleration // disable linux hardware acceleration
const disableLinuxHardwareAccelerationInput = core.getInput('disable-linux-hw-accel'); let disableLinuxHardwareAccelerationInput = core.getInput('disable-linux-hw-accel');
input_validator_1.checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAccelerationInput); input_validator_1.checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAccelerationInput);
if (disableLinuxHardwareAccelerationInput === 'auto' && process.platform === 'linux') {
disableLinuxHardwareAccelerationInput = linuxSupportKVM ? 'false' : 'true';
}
const disableLinuxHardwareAcceleration = disableLinuxHardwareAccelerationInput === 'true'; const disableLinuxHardwareAcceleration = disableLinuxHardwareAccelerationInput === 'true';
console.log(`disable Linux hardware acceleration: ${disableLinuxHardwareAcceleration}`); console.log(`disable Linux hardware acceleration: ${disableLinuxHardwareAcceleration}`);
// enable hardware keyboard // enable hardware keyboard
@@ -141,10 +159,11 @@ function run() {
scripts.forEach((script) => __awaiter(this, void 0, void 0, function* () { scripts.forEach((script) => __awaiter(this, void 0, void 0, function* () {
console.log(`${script}`); console.log(`${script}`);
})); }));
console.log(`::endgroup::`);
// install SDK // install SDK
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion); yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
// launch an emulator // launch an emulator
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, ramSize, sdcardPathOrSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard); yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard);
// execute the custom script // execute the custom script
try { try {
// move to custom working directory if set // move to custom working directory if set
+47 -41
View File
@@ -34,54 +34,60 @@ const exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io")); const io = __importStar(require("@actions/io"));
const tc = __importStar(require("@actions/tool-cache")); const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const BUILD_TOOLS_VERSION = '31.0.0'; const BUILD_TOOLS_VERSION = '33.0.0';
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-7583922_latest.zip'; const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-8512546_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-7583922_latest.zip'; const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-8512546_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, * 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. * and the system image for the chosen API level, CPU arch, and target.
*/ */
function installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion) { function installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const isOnMac = process.platform === 'darwin'; try {
if (!isOnMac) { console.log(`::group::Install Android SDK`);
yield exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_SDK_ROOT} -R`); const isOnMac = process.platform === 'darwin';
if (!isOnMac) {
yield exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_SDK_ROOT} -R`);
}
const cmdlineToolsPath = `${process.env.ANDROID_SDK_ROOT}/cmdline-tools`;
if (!fs.existsSync(cmdlineToolsPath)) {
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
const downloadPath = yield tc.downloadTool(sdkUrl);
yield tc.extractZip(downloadPath, cmdlineToolsPath);
yield io.mv(`${cmdlineToolsPath}/cmdline-tools`, `${cmdlineToolsPath}/latest`);
}
// add paths for commandline-tools and platform-tools
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`);
// 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}.`);
// 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');
}
console.log('Installing system images.');
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}' --channel=${channelId} > /dev/null"`);
}
if (cmakeVersion) {
console.log(`Installing CMake ${cmakeVersion}.`);
yield exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' --channel=${channelId} > /dev/null"`);
}
} }
const cmdlineToolsPath = `${process.env.ANDROID_SDK_ROOT}/cmdline-tools`; finally {
if (!fs.existsSync(cmdlineToolsPath)) { console.log(`::endgroup::`);
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
const downloadPath = yield tc.downloadTool(sdkUrl);
yield tc.extractZip(downloadPath, cmdlineToolsPath);
yield io.mv(`${cmdlineToolsPath}/cmdline-tools`, `${cmdlineToolsPath}/latest`);
}
// add paths for commandline-tools and platform-tools
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`);
// 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}.`);
// 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');
}
console.log('Installing system images.');
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}' --channel=${channelId} > /dev/null"`);
}
if (cmakeVersion) {
console.log(`Installing CMake ${cmakeVersion}.`);
yield exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' --channel=${channelId} > /dev/null"`);
} }
}); });
} }
+3 -3
View File
@@ -74,9 +74,9 @@
} }
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "6.3.0", "version": "6.3.0",
+6 -2
View File
@@ -70,7 +70,7 @@ module.exports = function (args, opts) {
var o = obj; var o = obj;
for (var i = 0; i < keys.length-1; i++) { for (var i = 0; i < keys.length-1; i++) {
var key = keys[i]; var key = keys[i];
if (key === '__proto__') return; if (isConstructorOrProto(o, key)) return;
if (o[key] === undefined) o[key] = {}; if (o[key] === undefined) o[key] = {};
if (o[key] === Object.prototype || o[key] === Number.prototype if (o[key] === Object.prototype || o[key] === Number.prototype
|| o[key] === String.prototype) o[key] = {}; || o[key] === String.prototype) o[key] = {};
@@ -79,7 +79,7 @@ module.exports = function (args, opts) {
} }
var key = keys[keys.length - 1]; var key = keys[keys.length - 1];
if (key === '__proto__') return; if (isConstructorOrProto(o, key)) return;
if (o === Object.prototype || o === Number.prototype if (o === Object.prototype || o === Number.prototype
|| o === String.prototype) o = {}; || o === String.prototype) o = {};
if (o === Array.prototype) o = []; if (o === Array.prototype) o = [];
@@ -243,3 +243,7 @@ function isNumber (x) {
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
} }
function isConstructorOrProto (obj, key) {
return key === 'constructor' && typeof obj[key] === 'function' || key === '__proto__';
}
+22 -57
View File
@@ -1,67 +1,16 @@
{ {
"_args": [ "name": "minimist",
[ "version": "1.2.6",
"minimist@1.2.5",
"/Users/Yang/Desktop/Projects/android-emulator-runner"
]
],
"_from": "minimist@1.2.5",
"_id": "minimist@1.2.5",
"_inBundle": false,
"_integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"_location": "/minimist",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "minimist@1.2.5",
"name": "minimist",
"escapedName": "minimist",
"rawSpec": "1.2.5",
"saveSpec": null,
"fetchSpec": "1.2.5"
},
"_requiredBy": [
"/",
"/@babel/core/json5",
"/@cnakazawa/watch",
"/json5",
"/sane"
],
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"_spec": "1.2.5",
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/minimist/issues"
},
"description": "parse argument options", "description": "parse argument options",
"main": "index.js",
"devDependencies": { "devDependencies": {
"covert": "^1.0.0", "covert": "^1.0.0",
"tap": "~0.4.0", "tap": "~0.4.0",
"tape": "^3.5.0" "tape": "^3.5.0"
}, },
"homepage": "https://github.com/substack/minimist",
"keywords": [
"argv",
"getopt",
"parser",
"optimist"
],
"license": "MIT",
"main": "index.js",
"name": "minimist",
"repository": {
"type": "git",
"url": "git://github.com/substack/minimist.git"
},
"scripts": { "scripts": {
"coverage": "covert test/*.js", "test": "tap test/*.js",
"test": "tap test/*.js" "coverage": "covert test/*.js"
}, },
"testling": { "testling": {
"files": "test/*.js", "files": "test/*.js",
@@ -76,5 +25,21 @@
"opera/12" "opera/12"
] ]
}, },
"version": "1.2.5" "repository": {
"type": "git",
"url": "git://github.com/substack/minimist.git"
},
"homepage": "https://github.com/substack/minimist",
"keywords": [
"argv",
"getopt",
"parser",
"optimist"
],
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"license": "MIT"
} }
+4 -1
View File
@@ -34,7 +34,10 @@ $ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
Previous versions had a prototype pollution bug that could cause privilege Previous versions had a prototype pollution bug that could cause privilege
escalation in some circumstances when handling untrusted user input. escalation in some circumstances when handling untrusted user input.
Please use version 1.2.3 or later: https://snyk.io/vuln/SNYK-JS-MINIMIST-559764 Please use version 1.2.6 or later:
* https://security.snyk.io/vuln/SNYK-JS-MINIMIST-2429795 (version <=1.2.5)
* https://snyk.io/vuln/SNYK-JS-MINIMIST-559764 (version <=1.2.3)
# methods # methods
+16
View File
@@ -42,3 +42,19 @@ test('proto pollution (constructor)', function (t) {
t.equal(argv.y, undefined); t.equal(argv.y, undefined);
t.end(); t.end();
}); });
test('proto pollution (constructor function)', function (t) {
var argv = parse(['--_.concat.constructor.prototype.y', '123']);
function fnToBeTested() {}
t.equal(fnToBeTested.y, undefined);
t.equal(argv.y, undefined);
t.end();
});
// powered by snyk - https://github.com/backstage/backstage/issues/10343
test('proto pollution (constructor function) snyk', function (t) {
var argv = parse('--_.constructor.constructor.prototype.foo bar'.split(' '));
t.equal((function(){}).foo, undefined);
t.equal(argv.y, undefined);
t.end();
})
+7 -7
View File
@@ -12,7 +12,7 @@
"@actions/core": "^1.6.0", "@actions/core": "^1.6.0",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.0",
"@actions/tool-cache": "^1.7.1", "@actions/tool-cache": "^1.7.1",
"minimist": "^1.2.5", "minimist": "^1.2.6",
"set-value": "^4.1.0" "set-value": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
@@ -8508,9 +8508,9 @@
} }
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
}, },
"node_modules/mixin-deep": { "node_modules/mixin-deep": {
"version": "1.3.2", "version": "1.3.2",
@@ -17432,9 +17432,9 @@
} }
}, },
"minimist": { "minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
}, },
"mixin-deep": { "mixin-deep": {
"version": "1.3.2", "version": "1.3.2",
+1 -1
View File
@@ -24,7 +24,7 @@
"@actions/core": "^1.6.0", "@actions/core": "^1.6.0",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.0",
"@actions/tool-cache": "^1.7.1", "@actions/tool-cache": "^1.7.1",
"minimist": "^1.2.5", "minimist": "^1.2.6",
"set-value": "^4.1.0" "set-value": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
+66 -48
View File
@@ -13,7 +13,9 @@ export async function launchEmulator(
profile: string, profile: string,
cores: string, cores: string,
ramSize: string, ramSize: string,
heapSize: string,
sdcardPathOrSize: string, sdcardPathOrSize: string,
diskSize: string,
avdName: string, avdName: string,
forceAvdCreation: boolean, forceAvdCreation: boolean,
emulatorOptions: string, emulatorOptions: string,
@@ -22,63 +24,76 @@ export async function launchEmulator(
disableLinuxHardwareAcceleration: boolean, disableLinuxHardwareAcceleration: boolean,
enableHardwareKeyboard: boolean enableHardwareKeyboard: boolean
): Promise<void> { ): Promise<void> {
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true try {
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`; console.log(`::group::Launch Emulator`);
if (!fs.existsSync(avdPath) || forceAvdCreation) { // create a new AVD if AVD directory does not already exist or forceAvdCreation is true
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : ''; const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : ''; if (!fs.existsSync(avdPath) || forceAvdCreation) {
console.log(`Creating AVD.`); const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
await exec.exec( const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : '';
`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"` console.log(`Creating AVD.`);
); await exec.exec(
} `sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`
);
}
if (cores) { if (cores) {
await exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`); await exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
} }
if (ramSize) { if (ramSize) {
await exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`); await exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
} }
if (enableHardwareKeyboard) { if (heapSize) {
await exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`); await exec.exec(`sh -c \\"printf 'hw.heapSize=${heapSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
} }
//turn off hardware acceleration on Linux if (enableHardwareKeyboard) {
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) { await exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
console.log('Disabling Linux hardware acceleration.'); }
emulatorOptions += ' -accel off';
}
// start emulator if (diskSize) {
console.log('Starting emulator.'); await exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
}
await exec.exec(`sh -c \\"${process.env.ANDROID_SDK_ROOT}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], { //turn off hardware acceleration on Linux
listeners: { if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
stderr: (data: Buffer) => { console.log('Disabling Linux hardware acceleration.');
if (data.toString().includes('invalid command-line parameter')) { emulatorOptions += ' -accel off';
throw new Error(data.toString()); }
// start emulator
console.log('Starting emulator.');
await exec.exec(`sh -c \\"${process.env.ANDROID_SDK_ROOT}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], {
listeners: {
stderr: (data: Buffer) => {
if (data.toString().includes('invalid command-line parameter')) {
throw new Error(data.toString());
}
} }
} }
});
// wait for emulator to complete booting
await waitForDevice();
await exec.exec(`adb shell input keyevent 82`);
if (disableAnimations) {
console.log('Disabling animations.');
await exec.exec(`adb shell settings put global window_animation_scale 0.0`);
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
} }
}); if (disableSpellChecker) {
await exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
// wait for emulator to complete booting }
await waitForDevice(); if (enableHardwareKeyboard) {
await exec.exec(`adb shell input keyevent 82`); await exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
}
if (disableAnimations) { } finally {
console.log('Disabling animations.'); console.log(`::endgroup::`);
await exec.exec(`adb shell settings put global window_animation_scale 0.0`);
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
}
if (disableSpellChecker) {
await exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
}
if (enableHardwareKeyboard) {
await exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
} }
} }
@@ -87,9 +102,12 @@ export async function launchEmulator(
*/ */
export async function killEmulator(): Promise<void> { export async function killEmulator(): Promise<void> {
try { try {
console.log(`::group::Terminate Emulator`);
await exec.exec(`adb -s emulator-5554 emu kill`); await exec.exec(`adb -s emulator-5554 emu kill`);
} catch (error) { } catch (error) {
console.log(error.message); console.log(error.message);
} finally {
console.log(`::endgroup::`);
} }
} }
+19 -2
View File
@@ -49,8 +49,8 @@ export function checkDisableSpellchecker(disableSpellchecker: string): void {
} }
export function checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAcceleration: string): void { export function checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAcceleration: string): void {
if (!isValidBoolean(disableLinuxHardwareAcceleration)) { if (!(isValidBoolean(disableLinuxHardwareAcceleration) || disableLinuxHardwareAcceleration === 'auto')) {
throw new Error(`Input for input.disable-linux-hw-accel should be either 'true' or 'false'.`); throw new Error(`Input for input.disable-linux-hw-accel should be either 'true' or 'false' or 'auto'.`);
} }
} }
@@ -69,3 +69,20 @@ export function checkEmulatorBuild(emulatorBuild: string): void {
function isValidBoolean(value: string): boolean { function isValidBoolean(value: string): boolean {
return value === 'true' || value === 'false'; return value === 'true' || value === 'false';
} }
export function checkDiskSize(diskSize: string): void {
// Disk size can be empty - the default value
if (diskSize) {
// Can also be number of bytes
if (isNaN(Number(diskSize)) || !Number.isInteger(Number(diskSize))) {
// Disk size can have a size multiplier at the end K, M or G
const diskSizeUpperCase = diskSize.toUpperCase();
if (diskSizeUpperCase.endsWith('K') || diskSizeUpperCase.endsWith('M') || diskSizeUpperCase.endsWith('G')) {
const diskSizeNoModifier: string = diskSize.slice(0, -1);
if (0 == diskSizeNoModifier.length || isNaN(Number(diskSizeNoModifier)) || !Number.isInteger(Number(diskSizeNoModifier))) {
throw new Error(`Unexpected disk size: '${diskSize}'.`);
}
}
}
}
}
+28 -5
View File
@@ -10,21 +10,30 @@ import {
checkDisableLinuxHardwareAcceleration, checkDisableLinuxHardwareAcceleration,
checkForceAvdCreation, checkForceAvdCreation,
checkChannel, checkChannel,
checkEnableHardwareKeyboard checkEnableHardwareKeyboard,
checkDiskSize
} from './input-validator'; } from './input-validator';
import { launchEmulator, killEmulator } from './emulator-manager'; import { launchEmulator, killEmulator } from './emulator-manager';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import { parseScript } from './script-parser'; import { parseScript } from './script-parser';
import { getChannelId } from './channel-id-mapper'; import { getChannelId } from './channel-id-mapper';
import { accessSync, constants } from 'fs';
async function run() { async function run() {
try { try {
console.log(`::group::Configure emulator`);
let linuxSupportKVM = false;
// only support running on macOS or Linux // only support running on macOS or Linux
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
if (process.platform === 'linux') { if (process.platform === 'linux') {
console.warn( try {
`You're running a Linux VM where hardware acceleration is not available. Please consider using a macOS VM instead to take advantage of native hardware acceleration support provided by HAXM.` accessSync('/dev/kvm', constants.R_OK | constants.W_OK);
); linuxSupportKVM = true;
} catch {
console.warn(
`You're running a Linux VM where hardware acceleration is not available. Please consider using a macOS VM instead to take advantage of native hardware acceleration support provided by HAXM.`
);
}
} else { } else {
throw new Error('Unsupported virtual machine: please use either macos or ubuntu VM.'); throw new Error('Unsupported virtual machine: please use either macos or ubuntu VM.');
} }
@@ -59,10 +68,18 @@ async function run() {
const ramSize = core.getInput('ram-size'); const ramSize = core.getInput('ram-size');
console.log(`RAM size: ${ramSize}`); console.log(`RAM size: ${ramSize}`);
// Heap size to use for AVD
const heapSize = core.getInput('heap-size');
console.log(`Heap size: ${heapSize}`);
// SD card path or size used for creating the AVD // SD card path or size used for creating the AVD
const sdcardPathOrSize = core.getInput('sdcard-path-or-size'); const sdcardPathOrSize = core.getInput('sdcard-path-or-size');
console.log(`SD card path or size: ${sdcardPathOrSize}`); console.log(`SD card path or size: ${sdcardPathOrSize}`);
const diskSize = core.getInput('disk-size');
checkDiskSize(diskSize);
console.log(`Disk size: ${diskSize}`);
// custom name used for creating the AVD // custom name used for creating the AVD
const avdName = core.getInput('avd-name'); const avdName = core.getInput('avd-name');
console.log(`AVD name: ${avdName}`); console.log(`AVD name: ${avdName}`);
@@ -90,8 +107,11 @@ async function run() {
console.log(`disable spellchecker: ${disableSpellchecker}`); console.log(`disable spellchecker: ${disableSpellchecker}`);
// disable linux hardware acceleration // disable linux hardware acceleration
const disableLinuxHardwareAccelerationInput = core.getInput('disable-linux-hw-accel'); let disableLinuxHardwareAccelerationInput = core.getInput('disable-linux-hw-accel');
checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAccelerationInput); checkDisableLinuxHardwareAcceleration(disableLinuxHardwareAccelerationInput);
if (disableLinuxHardwareAccelerationInput === 'auto' && process.platform === 'linux') {
disableLinuxHardwareAccelerationInput = linuxSupportKVM ? 'false' : 'true';
}
const disableLinuxHardwareAcceleration = disableLinuxHardwareAccelerationInput === 'true'; const disableLinuxHardwareAcceleration = disableLinuxHardwareAccelerationInput === 'true';
console.log(`disable Linux hardware acceleration: ${disableLinuxHardwareAcceleration}`); console.log(`disable Linux hardware acceleration: ${disableLinuxHardwareAcceleration}`);
@@ -143,6 +163,7 @@ async function run() {
scripts.forEach(async (script: string) => { scripts.forEach(async (script: string) => {
console.log(`${script}`); console.log(`${script}`);
}); });
console.log(`::endgroup::`);
// install SDK // install SDK
await installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion); await installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
@@ -155,7 +176,9 @@ async function run() {
profile, profile,
cores, cores,
ramSize, ramSize,
heapSize,
sdcardPathOrSize, sdcardPathOrSize,
diskSize,
avdName, avdName,
forceAvdCreation, forceAvdCreation,
emulatorOptions, emulatorOptions,
+47 -42
View File
@@ -4,63 +4,68 @@ import * as io from '@actions/io';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import * as fs from 'fs'; import * as fs from 'fs';
const BUILD_TOOLS_VERSION = '31.0.0'; const BUILD_TOOLS_VERSION = '33.0.0';
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-7583922_latest.zip'; const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-8512546_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-7583922_latest.zip'; const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-8512546_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, * 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. * and the system image for the chosen API level, CPU arch, and target.
*/ */
export async function installAndroidSdk(apiLevel: number, target: string, arch: string, channelId: number, 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'; try {
console.log(`::group::Install Android SDK`);
const isOnMac = process.platform === 'darwin';
if (!isOnMac) { if (!isOnMac) {
await exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_SDK_ROOT} -R`); await exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_SDK_ROOT} -R`);
} }
const cmdlineToolsPath = `${process.env.ANDROID_SDK_ROOT}/cmdline-tools`; const cmdlineToolsPath = `${process.env.ANDROID_SDK_ROOT}/cmdline-tools`;
if (!fs.existsSync(cmdlineToolsPath)) { if (!fs.existsSync(cmdlineToolsPath)) {
console.log('Installing new cmdline-tools.'); console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX; const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
const downloadPath = await tc.downloadTool(sdkUrl); const downloadPath = await tc.downloadTool(sdkUrl);
await tc.extractZip(downloadPath, cmdlineToolsPath); await tc.extractZip(downloadPath, cmdlineToolsPath);
await io.mv(`${cmdlineToolsPath}/cmdline-tools`, `${cmdlineToolsPath}/latest`); await io.mv(`${cmdlineToolsPath}/cmdline-tools`, `${cmdlineToolsPath}/latest`);
} }
// add paths for commandline-tools and platform-tools // add paths for commandline-tools and platform-tools
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_SDK_ROOT}/platform-tools`); core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_SDK_ROOT}/platform-tools`);
// set standard AVD path // set standard AVD path
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`); core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
// accept all Android SDK licenses // accept all Android SDK licenses
await exec.exec(`sh -c \\"yes | sdkmanager --licenses > /dev/null"`); await exec.exec(`sh -c \\"yes | sdkmanager --licenses > /dev/null"`);
console.log('Installing latest build tools, platform tools, and platform.'); 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"`); await exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools 'platforms;android-${apiLevel}' > /dev/null"`);
console.log('Installing latest emulator.'); console.log('Installing latest emulator.');
await exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`); await exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`);
if (emulatorBuild) { if (emulatorBuild) {
console.log(`Installing emulator build ${emulatorBuild}.`); console.log(`Installing emulator build ${emulatorBuild}.`);
// TODO find out the correct download URLs for all build ids // TODO find out the correct download URLs for all build ids
const downloadUrlSuffix = Number(emulatorBuild.charAt(0)) > 6 ? `_x64-${emulatorBuild}` : `-${emulatorBuild}`; 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(`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 exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_SDK_ROOT}`);
await io.rmRF('emulator.zip'); await io.rmRF('emulator.zip');
} }
console.log('Installing system images.'); console.log('Installing system images.');
await exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`); await exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
if (ndkVersion) { if (ndkVersion) {
console.log(`Installing NDK ${ndkVersion}.`); console.log(`Installing NDK ${ndkVersion}.`);
await exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' --channel=${channelId} > /dev/null"`); await exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' --channel=${channelId} > /dev/null"`);
} }
if (cmakeVersion) { if (cmakeVersion) {
console.log(`Installing CMake ${cmakeVersion}.`); console.log(`Installing CMake ${cmakeVersion}.`);
await exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' --channel=${channelId} > /dev/null"`); await exec.exec(`sh -c \\"sdkmanager --install 'cmake;${cmakeVersion}' --channel=${channelId} > /dev/null"`);
}
} finally {
console.log(`::endgroup::`);
} }
} }
+3 -3
View File
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
android { android {
compileSdkVersion 31 compileSdkVersion 33
buildToolsVersion "31.0.0" buildToolsVersion "33.0.0"
defaultConfig { defaultConfig {
applicationId "com.example.testapp" applicationId "com.example.testapp"
minSdkVersion 15 minSdkVersion 15
targetSdkVersion 31 targetSdkVersion 33
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
+4 -4
View File
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.5.30' ext.kotlin_version = '1.7.0'
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.1' classpath 'com.android.tools.build:gradle:7.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
@@ -18,7 +18,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip