Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ubuntu): verify command line tools is the version we want #411

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ jobs:
| `enable-hw-keyboard` | Optional | `false` | Whether to enable hardware keyboard - `true` or `false`. |
| `emulator-build` | Optional | N/A | Build number of a specific version of the emulator binary to use e.g. `6061023` for emulator v29.3.0.0. |
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. Will be used for `script` & `pre-emulator-launch-script`. |
| `force-cmdline-tools-update` | Optional | `true` | Whether to update any pre-installed version of cmdline-tools if out of date. |
| `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` |
Expand Down
8 changes: 7 additions & 1 deletion lib/input-validator.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkPort = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.PREVIEW_API_LEVELS = exports.MAX_PORT = exports.MIN_PORT = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
exports.checkDiskSize = exports.checkForceCommandLineToolsUpdate = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkPort = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.PREVIEW_API_LEVELS = exports.MAX_PORT = exports.MIN_PORT = 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', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
Expand Down Expand Up @@ -82,6 +82,12 @@ function checkEmulatorBuild(emulatorBuild) {
}
}
exports.checkEmulatorBuild = checkEmulatorBuild;
function checkForceCommandLineToolsUpdate(forceCmdlineToolsUpdate) {
if (!isValidBoolean(forceCmdlineToolsUpdate)) {
throw new Error(`Input for input.force-cmdline-tools-update should be either 'true' or 'false'.`);
}
}
exports.checkForceCommandLineToolsUpdate = checkForceCommandLineToolsUpdate;
function isValidBoolean(value) {
return value === 'true' || value === 'false';
}
Expand Down
7 changes: 6 additions & 1 deletion lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ function run() {
(0, input_validator_1.checkForceAvdCreation)(forceAvdCreationInput);
const forceAvdCreation = forceAvdCreationInput === 'true';
console.log(`force avd creation: ${forceAvdCreation}`);
// force cmdline-tools update
const forceCmdlineToolsUpdateInput = core.getInput('force-cmdline-tools-update');
(0, input_validator_1.checkForceCommandLineToolsUpdate)(forceCmdlineToolsUpdateInput);
const forceCmdlineToolsUpdate = forceCmdlineToolsUpdateInput === 'true';
console.log(`force cmdline-tools update: ${forceCmdlineToolsUpdate}`);
// Emulator boot timeout seconds
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
Expand Down Expand Up @@ -179,7 +184,7 @@ function run() {
}));
console.log(`::endgroup::`);
// install SDK
yield (0, sdk_installer_1.installAndroidSdk)(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
yield (0, sdk_installer_1.installAndroidSdk)(apiLevel, target, arch, channelId, forceCmdlineToolsUpdate, emulatorBuild, ndkVersion, cmakeVersion);
// execute pre emulator launch script if set
if (preEmulatorLaunchScripts !== undefined) {
console.log(`::group::Run pre emulator launch script`);
Expand Down
19 changes: 16 additions & 3 deletions lib/sdk-installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,34 @@ const io = __importStar(require("@actions/io"));
const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs"));
const BUILD_TOOLS_VERSION = '35.0.0';
// SDK command-line tools 16.0
const CMDLINE_TOOLS_VERSION = '16.0'; // the downloads immediately below should correspond to this version
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-12266719_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-12266719_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, channelId, emulatorBuild, ndkVersion, cmakeVersion) {
function installAndroidSdk(apiLevel, target, arch, channelId, forceCmdlineToolsUpdate, emulatorBuild, ndkVersion, cmakeVersion) {
return __awaiter(this, void 0, void 0, function* () {
try {
console.log(`::group::Install Android SDK`);
const isOnMac = process.platform === 'darwin';
const isArm = process.arch === 'arm64';
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
if (!fs.existsSync(cmdlineToolsPath)) {
// it may happen that cmdlineToolsPath exists, but is older than desired
// this can cause problems when sdkmanager XML manifest versions change
// for example ubuntu-24 has cmdline-tools v12 with XML v3 but v16 supports v4
if (forceCmdlineToolsUpdate && fs.existsSync(`${cmdlineToolsPath}/latest`)) {
const cmdlineToolsVer = (yield exec.getExecOutput(`sh -c "${cmdlineToolsPath}/latest/bin/sdkmanager --version"`)).stdout.trim();
if (!cmdlineToolsVer.includes(CMDLINE_TOOLS_VERSION)) {
console.log(`cmdline-tools is version ${cmdlineToolsVer} instead of expected ${CMDLINE_TOOLS_VERSION}. Removing.`);
yield io.rmRF(`${cmdlineToolsPath}/latest"`);
}
else {
console.log(`cmdline-tools is expected version ${CMDLINE_TOOLS_VERSION}: "${cmdlineToolsVer}"`);
}
}
if (!fs.existsSync(`${cmdlineToolsPath}/latest`)) {
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
const downloadPath = yield tc.downloadTool(sdkUrl);
Expand Down
6 changes: 6 additions & 0 deletions src/input-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ export function checkEmulatorBuild(emulatorBuild: string): void {
}
}

export function checkForceCommandLineToolsUpdate(forceCmdlineToolsUpdate: string): void {
if (!isValidBoolean(forceCmdlineToolsUpdate)) {
throw new Error(`Input for input.force-cmdline-tools-update should be either 'true' or 'false'.`);
}
}

function isValidBoolean(value: string): boolean {
return value === 'true' || value === 'false';
}
Expand Down
9 changes: 8 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
checkDisableSpellchecker,
checkDisableLinuxHardwareAcceleration,
checkForceAvdCreation,
checkForceCommandLineToolsUpdate,
checkChannel,
checkEnableHardwareKeyboard,
checkDiskSize,
Expand Down Expand Up @@ -92,6 +93,12 @@ async function run() {
const forceAvdCreation = forceAvdCreationInput === 'true';
console.log(`force avd creation: ${forceAvdCreation}`);

// force cmdline-tools update
const forceCmdlineToolsUpdateInput = core.getInput('force-cmdline-tools-update');
checkForceCommandLineToolsUpdate(forceCmdlineToolsUpdateInput);
const forceCmdlineToolsUpdate = forceCmdlineToolsUpdateInput === 'true';
console.log(`force cmdline-tools update: ${forceCmdlineToolsUpdate}`);

// Emulator boot timeout seconds
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
Expand Down Expand Up @@ -185,7 +192,7 @@ async function run() {
console.log(`::endgroup::`);

// install SDK
await installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
await installAndroidSdk(apiLevel, target, arch, channelId, forceCmdlineToolsUpdate, emulatorBuild, ndkVersion, cmakeVersion);

// execute pre emulator launch script if set
if (preEmulatorLaunchScripts !== undefined) {
Expand Down
20 changes: 17 additions & 3 deletions src/sdk-installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,36 @@ import * as tc from '@actions/tool-cache';
import * as fs from 'fs';

const BUILD_TOOLS_VERSION = '35.0.0';
// SDK command-line tools 16.0
const CMDLINE_TOOLS_VERSION = '16.0'; // the downloads immediately below should correspond to this version
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-12266719_latest.zip';
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-12266719_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: string, target: string, arch: string, channelId: number, emulatorBuild?: string, ndkVersion?: string, cmakeVersion?: string): Promise<void> {
export async function installAndroidSdk(apiLevel: string, target: string, arch: string, channelId: number, forceCmdlineToolsUpdate: boolean, emulatorBuild?: string, ndkVersion?: string, cmakeVersion?: string): Promise<void> {
try {
console.log(`::group::Install Android SDK`);
const isOnMac = process.platform === 'darwin';
const isArm = process.arch === 'arm64';

const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
if (!fs.existsSync(cmdlineToolsPath)) {

// it may happen that cmdlineToolsPath exists, but is older than desired
// this can cause problems when sdkmanager XML manifest versions change
// for example ubuntu-24 has cmdline-tools v12 with XML v3 but v16 supports v4
if (forceCmdlineToolsUpdate && fs.existsSync(`${cmdlineToolsPath}/latest`)) {
const cmdlineToolsVer = (await exec.getExecOutput(`sh -c "${cmdlineToolsPath}/latest/bin/sdkmanager --version"`)).stdout.trim();
if (!cmdlineToolsVer.includes(CMDLINE_TOOLS_VERSION)) {
console.log(`cmdline-tools is version ${cmdlineToolsVer} instead of expected ${CMDLINE_TOOLS_VERSION}. Removing.`);
await io.rmRF(`${cmdlineToolsPath}/latest"`);
} else {
console.log(`cmdline-tools is expected version ${CMDLINE_TOOLS_VERSION}: "${cmdlineToolsVer}"`);
}
}

if (!fs.existsSync(`${cmdlineToolsPath}/latest`)) {
console.log('Installing new cmdline-tools.');
const sdkUrl = isOnMac ? CMDLINE_TOOLS_URL_MAC : CMDLINE_TOOLS_URL_LINUX;
const downloadPath = await tc.downloadTool(sdkUrl);
Expand Down