17 Commits

Author SHA1 Message Date
Vilius Sutkus '89
07976c6290 [CI] Don't log licenses 2023-11-25 18:10:19 +02:00
Vilius Sutkus '89
56927e38e2 Update npm dependencies 2023-11-25 18:04:24 +02:00
Vilius Sutkus '89
eb7920b260 Implement action input parameter 'packages' 2023-11-25 17:41:26 +02:00
Vilius Sutkus '89
a86cdbf03d [CI] Call this action by calling action.yml
action.yml has default input arguments. Would rather not duplicate them in CI workflow
2023-11-25 17:25:16 +02:00
Vilius Sutkus '89
713cbf481b [README.md] Update wording about licenses 2023-11-25 17:22:28 +02:00
Vilius Sutkus '89
1297b09c09 [CI] List installed packages 2023-11-25 17:21:46 +02:00
Vilius Sutkus '89
d24156dbc9 [README.md] Add a note about installed packages 2023-11-21 22:41:46 +02:00
Vilius Sutkus '89
ade8112388 Change "Licence" to "License" 2023-11-21 22:35:25 +02:00
Vilius Sutkus '89
aeaba18a12 [Issue #384] Implement silent licence agreement. 2023-11-21 22:11:35 +02:00
Vilius Sutkus '89
423241b186 Don't eslint warn about English text in string literals 2023-11-21 21:35:16 +02:00
Vilius Sutkus '89
4113fd9036 [CI] Test all cmdlinetools versions 2023-11-21 21:32:42 +02:00
Vilius Sutkus '89
0549df86ae Update npm dependencies 2023-11-21 21:27:27 +02:00
Vilius Sutkus '89
b6023dae3a [CI] Update actions/setup-node to v4 2023-11-21 21:25:54 +02:00
Vilius Sutkus '89
ded9227d6b [CI] Update actions/checkout to v4 2023-11-21 21:25:09 +02:00
Vilius Sutkus '89
449627e76b Format file to match correct "desired" width. Remove leftover debug printout 2023-11-21 21:22:57 +02:00
Vilius Sutkus '89
8023252681 [Issue #192] Accept cmdline-tools-version input parameter 2023-11-21 21:18:33 +02:00
Vilius Sutkus '89
9584f05408 [README.md] Update version of this action 2023-09-25 04:30:57 +03:00
11 changed files with 25177 additions and 3914 deletions

View File

@@ -44,7 +44,7 @@
"semi": "off",
"@typescript-eslint/semi": ["error", "never"],
"@typescript-eslint/type-annotation-spacing": "error",
"i18n-text/no-en": "warn",
"i18n-text/no-en": "off",
"@typescript-eslint/unbound-method": "error"
},
"env": {

View File

@@ -15,10 +15,10 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20
@@ -32,10 +32,10 @@ jobs:
format-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20
@@ -46,10 +46,10 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20
@@ -59,16 +59,22 @@ jobs:
runSdkManager:
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} - ${{ matrix.cmdline-tools-version }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-20.04, ubuntu-22.04, macos-11, macos-12, macos-13, windows-2019, windows-2022 ]
cmdline-tools-version:
- 10406996
- 9862592
- 9477386
- 9123335
- 8512546
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20
@@ -81,17 +87,23 @@ jobs:
- run: npm ci
- run: npm run build
- run: node dist/index.js
- name: Run setup-android
uses: ./
with:
cmdline-tools-version: ${{ matrix.cmdline-tools-version }}
log-accepted-android-sdk-licenses: 'false'
- run: sdkmanager --list_installed
- run: sdkmanager --list
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20

View File

@@ -31,7 +31,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -27,11 +27,11 @@ jobs:
if: ${{ false }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
repository: daveol/SampleApplication
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
path: ./build/

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -23,7 +23,7 @@ See [action.yml](action.yml)
## Basic
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
@@ -32,12 +32,66 @@ steps:
distribution: 'temurin'
- name: Setup Android SDK
uses: android-actions/setup-android@v2
uses: android-actions/setup-android@v3
- name: Build SampleApplication
run: ./gradlew --no-daemon build
```
## Additional packages
Input parameter `packages` controls which packages this action will install from Android SDK.
Default value is `tools platform-tools`, supply an empty string to skip installing additional packages.
Additional packages can be installed at a later time by calling sdkmanager manually.
```yaml
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
packages: ''
# ...
- run: sdkmanager tools platform-tools
```
## SDK Version selection
Command line tools are versioned using two variables - short and long.
Long one is the build number, used in the zip URL, short one is the human friendly version name.
By default, setup-android installs version 10406996 (short version 11.0).
To install a different version, call setup-android with desired long version as the input parameter `cmdline-tools-version`:
```yaml
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
cmdline-tools-version: 8512546
```
#### Version table
| Short version | Long version |
| --- | --- |
| 11.0 | 10406996 |
| 10.0 | 9862592 |
| 9.0 | 9477386 |
| 8.0 | 9123335 |
| 7.0 | 8512546 |
Current cmdline tools version can be found at https://developer.android.com/studio#command-line-tools-only
# Android SDK Licenses
Android SDK is not public domain software, it comes with a license.
Input parameter `accept-android-sdk-licenses` decides if Android SDK licenses should be agreed to on behalf of the user of this action.
Default option is 'yes', because otherwise SDK is unusable until said licenses are agreed to.
licenses are quite long, to prevent a wall of text in the action output, licenses can be agreed to silently.
Input parameter `log-accepted-android-sdk-licenses` controls whether license texts should be printed or omitted from the text output. Defaults to 'true'.
# Thanks
Based on the project [android-problem-matchers-action](https://github.com/jonasb/android-problem-matchers-action) from [@jonasb](https://github.com/jonasb)

View File

@@ -2,6 +2,27 @@ name: 'Setup Android SDK Tools'
author: 'Android-Actions'
description: 'Setup the Android SDK Tools and add them to the path'
inputs:
cmdline-tools-version:
description: 'cmdline-tools-version. See https://developer.android.com/studio#command-line-tools-only'
required: false
default: '10406996'
accept-android-sdk-licenses:
description: 'Android SDK is usable only after the license agreement. Should setup-android agree to the licences, provided by "sdkmanager --licenses"'
required: false
default: 'true'
log-accepted-android-sdk-licenses:
description: 'Should accepted licenses be logged. If not, accepted licences will be accepted silently'
required: false
default: 'true'
packages:
description: 'Additional packages to install'
required: false
default: 'tools platform-tools'
runs:
using: node20
main: 'dist/index.js'

26649
dist/index.js vendored

File diff suppressed because one or more lines are too long

2065
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -27,11 +27,9 @@
"dependencies": {
"@actions/cache": "^3.2.2",
"@actions/core": "^1.10.1",
"@actions/tool-cache": "^2.0.1",
"fs-extra": "^11.1.1"
"@actions/tool-cache": "^2.0.1"
},
"devDependencies": {
"@types/fs-extra": "^11.0.2",
"@types/jest": "^29.5.5",
"@types/node": "^20.6.5",
"@typescript-eslint/eslint-plugin": "^6.7.2",

View File

@@ -3,109 +3,96 @@ import * as tc from '@actions/tool-cache'
import * as exec from '@actions/exec'
import * as path from 'path'
import * as fs from 'fs'
import * as fse from 'fs-extra'
import * as os from 'os'
const CMDLINE_TOOLS_VERSION = '11.0'
const COMMANDLINE_TOOLS_VERSION = '10406996'
function getVersionShort(versionLong: string): string {
switch (versionLong) {
case '10406996':
return '11.0'
case '9862592':
return '10.0'
case '9477386':
return '9.0'
case '9123335':
return '8.0'
case '8512546':
return '7.0'
default:
return versionLong
}
}
const COMMANDLINE_TOOLS_WIN_URL = `https://dl.google.com/android/repository/commandlinetools-win-${COMMANDLINE_TOOLS_VERSION}_latest.zip`
const COMMANDLINE_TOOLS_MAC_URL = `https://dl.google.com/android/repository/commandlinetools-mac-${COMMANDLINE_TOOLS_VERSION}_latest.zip`
const COMMANDLINE_TOOLS_LIN_URL = `https://dl.google.com/android/repository/commandlinetools-linux-${COMMANDLINE_TOOLS_VERSION}_latest.zip`
const VERSION_LONG = core.getInput('cmdline-tools-version', {
trimWhitespace: true
})
if (VERSION_LONG.includes('/') || VERSION_LONG.includes('\\')) {
core.setFailed('Malformed cmdline-tools-version!')
throw new Error('Malformed cmdline-tools-version!')
}
const VERSION_SHORT = getVersionShort(VERSION_LONG)
const HOME = os.homedir()
const ANDROID_HOME_DIR = path.join(HOME, '.android')
const ANDROID_HOME_SDK_DIR = path.join(ANDROID_HOME_DIR, 'sdk')
const COMMANDLINE_TOOLS_WIN_URL = `https://dl.google.com/android/repository/commandlinetools-win-${VERSION_LONG}_latest.zip`
const COMMANDLINE_TOOLS_MAC_URL = `https://dl.google.com/android/repository/commandlinetools-mac-${VERSION_LONG}_latest.zip`
const COMMANDLINE_TOOLS_LIN_URL = `https://dl.google.com/android/repository/commandlinetools-linux-${VERSION_LONG}_latest.zip`
const ANDROID_HOME_SDK_DIR = path.join(os.homedir(), '.android', 'sdk')
let ANDROID_SDK_ROOT = process.env['ANDROID_SDK_ROOT'] || ANDROID_HOME_SDK_DIR
function getSdkManagerPath(cmdToolsVersion: string): string {
return path.join(
ANDROID_SDK_ROOT,
'cmdline-tools',
cmdToolsVersion,
'bin',
'sdkmanager'
)
}
function findPreinstalledSdkManager(): {
isFound: boolean
isCorrectVersion: boolean
exePath: string
} {
const result = {isFound: false, isCorrectVersion: false, exePath: ''}
// First try to find the version defined in CMDLINE_TOOLS_VERSION
result.exePath = getSdkManagerPath(CMDLINE_TOOLS_VERSION)
result.isFound = fs.existsSync(result.exePath)
if (result.isFound) {
result.isCorrectVersion = true
return result
}
// cmdline-tools could have a 'latest' version, but if it was installed 2 years ago
// it may not be 'latest' as of today
result.exePath = getSdkManagerPath('latest')
result.isFound = fs.existsSync(result.exePath)
if (result.isFound) {
const propertiesFile = path.join(
ANDROID_SDK_ROOT,
'cmdline-tools',
'latest',
'source.properties'
)
if (fs.existsSync(propertiesFile)) {
result.isCorrectVersion = fs
.readFileSync(propertiesFile, 'utf8')
.includes(`Pkg.Revision=${CMDLINE_TOOLS_VERSION}`)
}
return result
}
result.exePath = ''
// Find whatever version is available in ANDROID_SDK_ROOT
const cmdlineToolsDir = path.join(ANDROID_SDK_ROOT, 'cmdline-tools')
const foundVersions: string[] = fs.existsSync(cmdlineToolsDir)
? fs.readdirSync(cmdlineToolsDir)
: []
const foundVersionsFiltered: string[] = foundVersions.filter(
obj => '.' !== obj && '..' !== obj
)
// Sort by desc, to get 2.0 first, before 1.0
const foundVersionsSorted: string[] = foundVersionsFiltered.sort(
(a: string, b: string) => (a > b ? -1 : 1)
)
for (const version of foundVersionsSorted) {
result.exePath = getSdkManagerPath(version)
result.isFound = fs.existsSync(result.exePath)
if (result.isFound) {
return result
}
}
result.exePath = ''
return result
}
async function callSdkManager(sdkManager: string, arg: string): Promise<void> {
async function callSdkManager(
sdkManager: string,
arg: string,
printOutput: Boolean = true
): Promise<void> {
const acceptBuffer = Buffer.from(Array(10).fill('y').join('\n'), 'utf8')
await exec.exec(sdkManager, [arg], {
input: acceptBuffer
input: acceptBuffer,
silent: !printOutput
})
}
async function installSdkManager(): Promise<string> {
fs.mkdirSync(ANDROID_SDK_ROOT, {recursive: true})
// touch $ANDROID_SDK_ROOT/repositories.cfg
fs.closeSync(
fs.openSync(path.join(ANDROID_SDK_ROOT, 'repositories.cfg'), 'w')
const cmdlineTools = path.join(
ANDROID_SDK_ROOT,
'cmdline-tools',
VERSION_SHORT
)
let sdkManagerExe = path.join(cmdlineTools, 'bin', 'sdkmanager')
const sdkManager = findPreinstalledSdkManager()
if (!sdkManager.isFound) {
if (!fs.existsSync(sdkManagerExe)) {
const latestCmdlineTools = path.join(
ANDROID_SDK_ROOT,
'cmdline-tools',
'latest'
)
const sourcePropertiesFile = path.join(
latestCmdlineTools,
'source.properties'
)
const latestSdkManagerExe = path.join(
latestCmdlineTools,
'bin',
'sdkmanager'
)
if (
fs.existsSync(latestCmdlineTools) &&
fs.existsSync(sourcePropertiesFile) &&
fs.existsSync(latestSdkManagerExe)
) {
const sourceProperties = fs.readFileSync(sourcePropertiesFile)
core.info(
`Found preinstalled sdkmanager in ${latestCmdlineTools} with following source.properties:`
)
core.info(sourceProperties.toString())
if (sourceProperties.includes(`Pkg.Revision=${VERSION_SHORT}`)) {
core.info(`Preinstalled sdkmanager has the correct version`)
sdkManagerExe = latestSdkManagerExe
} else {
core.info(`Wrong version in preinstalled sdkmanager`)
}
}
}
if (!fs.existsSync(sdkManagerExe)) {
let cmdlineToolsURL
if (process.platform === 'linux') {
cmdlineToolsURL = COMMANDLINE_TOOLS_LIN_URL
@@ -117,43 +104,27 @@ async function installSdkManager(): Promise<string> {
core.error(`Unsupported platform: ${process.platform}`)
return ''
}
core.info(`Downloading commandline tools from ${cmdlineToolsURL}`)
const cmdlineToolsZip = await tc.downloadTool(cmdlineToolsURL)
const cmdlineToolsExtractedLocation = await tc.extractZip(cmdlineToolsZip)
// Move cmdline-tools to where it would be if it was installed through sdkmanager
// Will allow calling sdkmanager without --sdk_root='..' argument
const desiredLocation = path.join(
ANDROID_SDK_ROOT,
'cmdline-tools',
CMDLINE_TOOLS_VERSION
)
// Create parent directory
fs.mkdirSync(path.dirname(desiredLocation), {recursive: true})
const extractTo = path.join(ANDROID_SDK_ROOT, 'cmdline-tools')
await tc.extractZip(cmdlineToolsZip, extractTo)
// Make sure we don't have leftover target directory (happens sometimes...)
if (fs.existsSync(desiredLocation)) fse.removeSync(desiredLocation)
// @TODO: use io.mv instead of fs-extra.moveSync once following issue is resolved:
// https://github.com/actions/toolkit/issues/706
fse.moveSync(
path.join(cmdlineToolsExtractedLocation, 'cmdline-tools'),
desiredLocation
)
fse.removeSync(cmdlineToolsExtractedLocation)
sdkManager.exePath = getSdkManagerPath(CMDLINE_TOOLS_VERSION)
sdkManager.isCorrectVersion = true
if (fs.existsSync(cmdlineTools)) {
core.info(`Removing leftovers from ${cmdlineTools}`)
fs.rmSync(cmdlineTools, {recursive: true})
}
fs.renameSync(path.join(extractTo, 'cmdline-tools'), cmdlineTools)
}
if (!sdkManager.isCorrectVersion) {
await callSdkManager(
sdkManager.exePath,
`cmdline-tools;${CMDLINE_TOOLS_VERSION}`
)
sdkManager.exePath = getSdkManagerPath(CMDLINE_TOOLS_VERSION)
}
return sdkManager.exePath
// touch $ANDROID_SDK_ROOT/repositories.cfg
fs.closeSync(
fs.openSync(path.join(ANDROID_SDK_ROOT, 'repositories.cfg'), 'w')
)
core.debug(`sdkmanager available at: ${sdkManagerExe}`)
return sdkManagerExe
}
async function run(): Promise<void> {
@@ -175,17 +146,36 @@ async function run(): Promise<void> {
}
}
const sdkManager = await installSdkManager()
core.debug(`sdkmanager installed to: ${sdkManager}`)
await callSdkManager(sdkManager, '--licenses')
await callSdkManager(sdkManager, 'tools')
await callSdkManager(sdkManager, 'platform-tools')
const sdkManagerExe = await installSdkManager()
core.setOutput('ANDROID_COMMANDLINE_TOOLS_VERSION', COMMANDLINE_TOOLS_VERSION)
if (core.getBooleanInput('accept-android-sdk-licenses')) {
core.info('Accepting Android SDK licenses')
await callSdkManager(
sdkManagerExe,
'--licenses',
core.getBooleanInput('log-accepted-android-sdk-licenses')
)
}
const packages = core
.getInput('packages', {required: false})
.split(' ')
.map(function (str) {
return str.trim()
})
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
.filter(function (element, index, array) {
return element
})
for (const pkg of packages) {
await callSdkManager(sdkManagerExe, pkg)
}
core.setOutput('ANDROID_COMMANDLINE_TOOLS_VERSION', VERSION_LONG)
core.exportVariable('ANDROID_HOME', ANDROID_SDK_ROOT)
core.exportVariable('ANDROID_SDK_ROOT', ANDROID_SDK_ROOT)
core.addPath(path.dirname(sdkManager))
core.addPath(path.dirname(sdkManagerExe))
core.addPath(path.join(ANDROID_SDK_ROOT, 'platform-tools'))
core.debug('add matchers')