mirror of
https://gitea.com/actions/setup-android.git
synced 2025-12-14 12:26:56 +00:00
Changeup: consilidate code, drop cache, change download
This changes up way too much: - Moving most (all) of the code to main.ts instead of the numerous files - Dropping the caching functionality, since it should be optional - now we will only download the android sdk tools if they are not already present, including if ANDROID_SDK_ROOT is already set
This commit is contained in:
189
src/cache.ts
189
src/cache.ts
@@ -1,189 +0,0 @@
|
||||
import * as glob from '@actions/glob'
|
||||
import * as cache from '@actions/cache'
|
||||
import * as core from '@actions/core'
|
||||
import * as crypto from 'crypto'
|
||||
import * as fs from 'fs'
|
||||
import {platform} from 'os'
|
||||
import {
|
||||
GRADLE_WRAPPER_GLOB,
|
||||
GRADLE_CACHE_GLOB,
|
||||
GRADLE_WRAPPER_DIR,
|
||||
GRADLE_CACHE_DIR,
|
||||
GRADLE_WRAPPER_KEY,
|
||||
GRADLE_CACHE_KEY,
|
||||
ANDROID_GLOB,
|
||||
ANDROID_KEY,
|
||||
COMMANDLINE_TOOLS_VERSION,
|
||||
ANDROID_SDK_ROOT,
|
||||
ANDROID_REPOSITORIES_CACHE,
|
||||
ANDROID_REPOSITORIES_CFG,
|
||||
VERSION
|
||||
} from './constants'
|
||||
|
||||
async function hashFiles(globs: string[]): Promise<string | undefined> {
|
||||
const globber = await glob.create(globs.join('\n'), {
|
||||
followSymbolicLinks: false
|
||||
})
|
||||
const hashes: Buffer[] = []
|
||||
|
||||
for await (const file of globber.globGenerator()) {
|
||||
// skip directories
|
||||
if (fs.statSync(file).isDirectory()) continue
|
||||
|
||||
core.debug(`hashFiles: found ${file}`)
|
||||
const hash = crypto.createHash('sha256')
|
||||
fs.createReadStream(file).pipe(hash)
|
||||
hashes.push(hash.digest())
|
||||
}
|
||||
|
||||
// No files hashed
|
||||
if (hashes.length === 0) {
|
||||
core.debug('hashFiles: no hashes in array')
|
||||
return
|
||||
}
|
||||
|
||||
// Loop trough files
|
||||
const completeHash = crypto.createHash('sha256')
|
||||
for (const hash of hashes) {
|
||||
completeHash.update(hash)
|
||||
}
|
||||
completeHash.end()
|
||||
return completeHash.digest('hex')
|
||||
}
|
||||
|
||||
export async function preGradleWrapper(): Promise<void> {
|
||||
const wrapperHash = await hashFiles(GRADLE_WRAPPER_GLOB)
|
||||
const wrapperKey = `gradle-wrapper-${platform}-${wrapperHash}`
|
||||
const wrapperRestoreKeys = [`gradle-wrapper-${platform}-`, `gradle-wrapper-`]
|
||||
|
||||
// if no wrapper is present skip trying to retrieve it
|
||||
if (!wrapperHash) {
|
||||
core.info('A hash for the gradle wrapper could not be generated')
|
||||
return
|
||||
}
|
||||
|
||||
const wrapperCache = await cache.restoreCache(
|
||||
[GRADLE_WRAPPER_DIR],
|
||||
wrapperKey,
|
||||
wrapperRestoreKeys
|
||||
)
|
||||
|
||||
if (!wrapperCache) {
|
||||
core.info(
|
||||
'Gradle wrapper cache not found, expect a download from gradle wrapper.'
|
||||
)
|
||||
}
|
||||
|
||||
if (wrapperCache !== wrapperKey) {
|
||||
core.saveState(GRADLE_WRAPPER_KEY, wrapperKey)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
export async function postGradleWrapper(): Promise<void> {
|
||||
const wrapperKey = core.getState(GRADLE_WRAPPER_KEY)
|
||||
|
||||
if (wrapperKey === '') {
|
||||
core.info(
|
||||
'A key for gradle wrapper was not defined, and thus there will not be a cache'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await cache.saveCache([GRADLE_WRAPPER_DIR], wrapperKey)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
export async function preGradleCache(): Promise<void> {
|
||||
const cacheHash = await hashFiles(GRADLE_CACHE_GLOB)
|
||||
const cacheKey = `gradle-cache-${platform}-${cacheHash}`
|
||||
const cacheRestoreKeys = [`gradle-cache-${platform}-`, `gradle-cache-`]
|
||||
|
||||
if (!cacheHash) {
|
||||
core.info('A hash for the gradle dependencies could not be generated')
|
||||
return
|
||||
}
|
||||
|
||||
const cacheCache = await cache.restoreCache(
|
||||
[GRADLE_CACHE_DIR],
|
||||
cacheKey,
|
||||
cacheRestoreKeys
|
||||
)
|
||||
|
||||
if (!cacheCache) {
|
||||
core.info('Gradle cache not found, expect dependency downloads from gradle')
|
||||
}
|
||||
|
||||
if (cacheCache !== cacheKey) {
|
||||
core.saveState(GRADLE_CACHE_KEY, cacheKey)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
export async function postGradleCache(): Promise<void> {
|
||||
const cacheKey = core.getState(GRADLE_CACHE_KEY)
|
||||
|
||||
if (cacheKey === '') {
|
||||
core.info(
|
||||
'A key for gradle cache was not defined, and thus there will not be a cache'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await cache.saveCache([GRADLE_CACHE_DIR], cacheKey)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
export async function preAndroidCache(): Promise<void> {
|
||||
const androidHash = await hashFiles(ANDROID_GLOB)
|
||||
const androidKey = `android-${VERSION}-${platform}-${COMMANDLINE_TOOLS_VERSION}-${androidHash}`
|
||||
const androidRestoreKeys = [
|
||||
`android-${VERSION}-${platform}-${COMMANDLINE_TOOLS_VERSION}-`,
|
||||
`android-${VERSION}-${platform}-`
|
||||
]
|
||||
|
||||
if (!androidHash) {
|
||||
core.info('A hash for the android sdk could not be generated')
|
||||
return
|
||||
}
|
||||
|
||||
const androidCache = await cache.restoreCache(
|
||||
[ANDROID_SDK_ROOT, ANDROID_REPOSITORIES_CACHE, ANDROID_REPOSITORIES_CFG],
|
||||
androidKey,
|
||||
androidRestoreKeys
|
||||
)
|
||||
|
||||
if (!androidCache) {
|
||||
core.info(
|
||||
'Android cache not found, expect dependency downloads from gradle'
|
||||
)
|
||||
}
|
||||
|
||||
if (androidCache !== androidKey) {
|
||||
core.saveState(ANDROID_KEY, androidKey)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
export async function postAndroidCache(): Promise<void> {
|
||||
const androidKey = core.getState(ANDROID_KEY)
|
||||
|
||||
if (androidKey === '') {
|
||||
core.info(
|
||||
'A key for the android sdk was not defined, and thus there will not be a cache'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await cache.saveCache(
|
||||
[ANDROID_SDK_ROOT, ANDROID_REPOSITORIES_CACHE, ANDROID_REPOSITORIES_CFG],
|
||||
androidKey
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import * as os from 'os'
|
||||
import * as path from 'path'
|
||||
|
||||
export const ANNOTATION_MATCHERS = [
|
||||
'android-lint-file-matcher.json',
|
||||
'android-lint-line-matcher.json',
|
||||
'gradle-matcher.json',
|
||||
'kotlin-error-matcher.json',
|
||||
'kotlin-warning-matcher.json'
|
||||
]
|
||||
|
||||
export const HOME = os.homedir()
|
||||
|
||||
export const VERSION = 'v1'
|
||||
|
||||
// Gradle constants
|
||||
// For caching the gradle cache in ~/.gradle/cache
|
||||
export const GRADLE_CACHE_GLOB = [
|
||||
'**/*.gradle',
|
||||
'**.gradle',
|
||||
'**/gradle.properties'
|
||||
]
|
||||
export const GRADLE_CACHE_DIR = path.join(HOME, '.gradle', 'cache')
|
||||
export const GRADLE_CACHE_KEY = 'GRADLE_CACHE_KEY'
|
||||
|
||||
// For caching the gradle wrapper in ~/.gradle/wrapper
|
||||
export const GRADLE_WRAPPER_GLOB = ['**/gradle/wrapper/**', '**/gradlew*']
|
||||
export const GRADLE_WRAPPER_DIR = path.join(HOME, '.gradle', 'wrapper')
|
||||
export const GRADLE_WRAPPER_KEY = 'GRADLE_WRAPPER_KEY'
|
||||
|
||||
// Android constants
|
||||
export const ANDROID_SDK_ROOT = path.join(HOME, 'android')
|
||||
export const ANDROID_GLOB = GRADLE_CACHE_GLOB
|
||||
export const ANDROID_KEY = 'ANDROID_KEY'
|
||||
|
||||
export const ANDROID_REPOSITORIES_DIR = path.join(HOME, '.android')
|
||||
export const ANDROID_REPOSITORIES_CFG = path.join(
|
||||
ANDROID_REPOSITORIES_DIR,
|
||||
'repositories.cfg'
|
||||
)
|
||||
export const ANDROID_REPOSITORIES_CACHE = path.join(
|
||||
ANDROID_REPOSITORIES_DIR,
|
||||
'cache'
|
||||
)
|
||||
|
||||
export const COMMANDLINE_TOOLS_VERSION = '6609375'
|
||||
export const COMMANDLINE_TOOLS_WIN_URL = `https://dl.google.com/android/repository/commandlinetools-win-${COMMANDLINE_TOOLS_VERSION}_latest.zip`
|
||||
export const COMMANDLINE_TOOLS_MAC_URL = `https://dl.google.com/android/repository/commandlinetools-mac-${COMMANDLINE_TOOLS_VERSION}_latest.zip`
|
||||
export const COMMANDLINE_TOOLS_LIN_URL = `https://dl.google.com/android/repository/commandlinetools-linux-${COMMANDLINE_TOOLS_VERSION}_latest.zip`
|
||||
@@ -1,58 +0,0 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as tc from '@actions/tool-cache'
|
||||
import {
|
||||
ANDROID_SDK_ROOT,
|
||||
COMMANDLINE_TOOLS_LIN_URL,
|
||||
COMMANDLINE_TOOLS_MAC_URL,
|
||||
COMMANDLINE_TOOLS_WIN_URL,
|
||||
ANDROID_REPOSITORIES_CFG,
|
||||
ANDROID_REPOSITORIES_DIR
|
||||
} from './constants'
|
||||
|
||||
export async function install(): Promise<void> {
|
||||
const licenseDir = path.join(ANDROID_SDK_ROOT, 'licenses')
|
||||
|
||||
// If the licences exist, the rest does too
|
||||
if (fs.existsSync(licenseDir) && fs.existsSync(ANDROID_REPOSITORIES_CFG)) {
|
||||
core.debug(`Skipping install, licenseDir found: ${licenseDir}`)
|
||||
return
|
||||
}
|
||||
|
||||
// create ~/.android/repositories.cfg
|
||||
fs.mkdirSync(ANDROID_REPOSITORIES_DIR, {recursive: true})
|
||||
fs.closeSync(fs.openSync(ANDROID_REPOSITORIES_CFG, 'w'))
|
||||
|
||||
const acceptBuffer = Buffer.from(Array(10).fill('y').join('\n'), 'utf8')
|
||||
let sdkManager = ''
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
const cmdlineToolsZip = await tc.downloadTool(COMMANDLINE_TOOLS_LIN_URL)
|
||||
const cmdlineTools = await tc.extractZip(cmdlineToolsZip)
|
||||
sdkManager = path.join(cmdlineTools, 'tools', 'bin', 'sdkmanager')
|
||||
} else if (process.platform === 'darwin') {
|
||||
const cmdlineToolsZip = await tc.downloadTool(COMMANDLINE_TOOLS_MAC_URL)
|
||||
const cmdlineTools = await tc.extractZip(cmdlineToolsZip)
|
||||
sdkManager = path.join(cmdlineTools, 'tools', 'bin', 'sdkmanager')
|
||||
} else if (process.platform === 'win32') {
|
||||
const cmdlineToolsZip = await tc.downloadTool(COMMANDLINE_TOOLS_WIN_URL)
|
||||
const cmdlineTools = await tc.extractZip(cmdlineToolsZip)
|
||||
sdkManager = path.join(cmdlineTools, 'tools', 'bin', 'sdkmanager.bat')
|
||||
} else {
|
||||
core.error(`Unsupported platform: ${process.platform}`)
|
||||
}
|
||||
|
||||
await exec.exec(
|
||||
sdkManager,
|
||||
['--licenses', `--sdk_root=${ANDROID_SDK_ROOT}`],
|
||||
{input: acceptBuffer}
|
||||
)
|
||||
|
||||
exec.exec(
|
||||
sdkManager,
|
||||
['--include_obsolete', `--sdk_root=${ANDROID_SDK_ROOT}`, 'tools'],
|
||||
{input: acceptBuffer}
|
||||
)
|
||||
}
|
||||
78
src/main.ts
78
src/main.ts
@@ -1,14 +1,71 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as tc from '@actions/tool-cache'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as path from 'path'
|
||||
import {ANDROID_SDK_ROOT, ANNOTATION_MATCHERS} from './constants'
|
||||
import {preGradleCache, preAndroidCache, preGradleWrapper} from './cache'
|
||||
import {install} from './install'
|
||||
import * as fs from 'fs'
|
||||
import * as os from 'os'
|
||||
|
||||
const COMMANDLINE_TOOLS_VERSION = '6609375'
|
||||
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 HOME = os.homedir()
|
||||
const ANDROID_HOME_DIR = path.join(HOME, '.android')
|
||||
const ANDROID_HOME_SDK_DIR = path.join(ANDROID_HOME_DIR, 'sdk')
|
||||
const ANDROID_REPOSITORIES_CFG = path.join(ANDROID_HOME_DIR, 'repositories.cfg')
|
||||
|
||||
async function install(): Promise<string> {
|
||||
const ANDROID_SDK_ROOT =
|
||||
process.env['ANDROID_SDK_ROOT'] || ANDROID_HOME_SDK_DIR
|
||||
const licenseDir = path.join(ANDROID_SDK_ROOT, 'licenses')
|
||||
|
||||
// If the licences exist, the rest does too
|
||||
if (fs.existsSync(licenseDir) && fs.existsSync(ANDROID_REPOSITORIES_CFG)) {
|
||||
core.debug(`Skipping install, licenseDir found: ${licenseDir}`)
|
||||
return ANDROID_SDK_ROOT
|
||||
}
|
||||
|
||||
// create ~/.android/repositories.cfg
|
||||
fs.mkdirSync(ANDROID_HOME_SDK_DIR, {recursive: true})
|
||||
fs.closeSync(fs.openSync(ANDROID_REPOSITORIES_CFG, 'w'))
|
||||
|
||||
const acceptBuffer = Buffer.from(Array(10).fill('y').join('\n'), 'utf8')
|
||||
let sdkManager = ''
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
const cmdlineToolsZip = await tc.downloadTool(COMMANDLINE_TOOLS_LIN_URL)
|
||||
const cmdlineTools = await tc.extractZip(cmdlineToolsZip)
|
||||
sdkManager = path.join(cmdlineTools, 'tools', 'bin', 'sdkmanager')
|
||||
} else if (process.platform === 'darwin') {
|
||||
const cmdlineToolsZip = await tc.downloadTool(COMMANDLINE_TOOLS_MAC_URL)
|
||||
const cmdlineTools = await tc.extractZip(cmdlineToolsZip)
|
||||
sdkManager = path.join(cmdlineTools, 'tools', 'bin', 'sdkmanager')
|
||||
} else if (process.platform === 'win32') {
|
||||
const cmdlineToolsZip = await tc.downloadTool(COMMANDLINE_TOOLS_WIN_URL)
|
||||
const cmdlineTools = await tc.extractZip(cmdlineToolsZip)
|
||||
sdkManager = path.join(cmdlineTools, 'tools', 'bin', 'sdkmanager.bat')
|
||||
} else {
|
||||
core.error(`Unsupported platform: ${process.platform}`)
|
||||
}
|
||||
|
||||
await exec.exec(
|
||||
sdkManager,
|
||||
['--licenses', `--sdk_root=${ANDROID_SDK_ROOT}`],
|
||||
{input: acceptBuffer}
|
||||
)
|
||||
|
||||
await exec.exec(
|
||||
sdkManager,
|
||||
['--include_obsolete', `--sdk_root=${ANDROID_SDK_ROOT}`, 'tools'],
|
||||
{input: acceptBuffer}
|
||||
)
|
||||
|
||||
return ANDROID_SDK_ROOT
|
||||
}
|
||||
|
||||
async function run(): Promise<void> {
|
||||
// process all caching but wait for them to all complete
|
||||
await Promise.all([preGradleWrapper(), preGradleCache(), preAndroidCache()])
|
||||
|
||||
await install()
|
||||
const ANDROID_SDK_ROOT = await install()
|
||||
|
||||
core.exportVariable('ANDROID_HOME', ANDROID_SDK_ROOT)
|
||||
core.exportVariable('ANDROID_SDK_ROOT', ANDROID_SDK_ROOT)
|
||||
@@ -17,11 +74,8 @@ async function run(): Promise<void> {
|
||||
core.addPath(path.join(ANDROID_SDK_ROOT, 'platform-tools'))
|
||||
|
||||
core.debug('add matchers')
|
||||
const matchersPath = path.join(__dirname, '..', '..', '.github')
|
||||
for (const matcher of ANNOTATION_MATCHERS) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`##[add-matcher]${path.join(matchersPath, matcher)}`)
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`##[add-matcher]${path.join(__dirname, '..', 'matchers.json')}`)
|
||||
}
|
||||
|
||||
run()
|
||||
|
||||
13
src/post.ts
13
src/post.ts
@@ -1,13 +0,0 @@
|
||||
import {postAndroidCache, postGradleCache, postGradleWrapper} from './cache'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
await Promise.all([
|
||||
postGradleCache(),
|
||||
postGradleWrapper(),
|
||||
postAndroidCache()
|
||||
])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
run()
|
||||
Reference in New Issue
Block a user