mirror of
https://github.com/gradle/gradle-build-action.git
synced 2024-12-25 14:46:18 +08:00
Cache Gradle distributions downloaded for a particular version (#58)
- Cache is separate from (but similar to) the wrapper distribution cache - New 'distributions-cache-enabled' flag controls caching of all downloaded distributions (including wrapper distributions) - Deprecated the 'wrapper-cache-enabled' flag for removal in v2
This commit is contained in:
parent
e4ec586f46
commit
33e91b639d
10
README.md
10
README.md
@ -122,22 +122,24 @@ jobs:
|
|||||||
|
|
||||||
This action provides 3 levels of caching to help speed up your GitHub Actions:
|
This action provides 3 levels of caching to help speed up your GitHub Actions:
|
||||||
|
|
||||||
- `wrapper` caches the local [wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) installation, saving time downloading and unpacking Gradle distributions ;
|
- `distributions` caches any downloaded Gradle zips, including any downloaded [wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) versions, saving time downloading Gradle distributions ;
|
||||||
- `dependencies` caches the [dependencies](https://docs.gradle.org/current/userguide/dependency_resolution.html#sub:cache_copy), saving time downloading dependencies ;
|
- `dependencies` caches the [dependencies](https://docs.gradle.org/current/userguide/dependency_resolution.html#sub:cache_copy), saving time downloading dependencies ;
|
||||||
- `configuration` caches the [build configuration](https://docs.gradle.org/nightly/userguide/configuration_cache.html), saving time configuring the build.
|
- `configuration` caches the [build configuration](https://docs.gradle.org/nightly/userguide/configuration_cache.html), saving time configuring the build.
|
||||||
|
|
||||||
Only the first one, caching the wrapper installation, is enabled by default.
|
Only the first one, caching downloaded distributions, is enabled by default.
|
||||||
Future versions of this action will enable all caching by default.
|
Future versions of this action will enable all caching by default.
|
||||||
|
|
||||||
You can control which level is enabled as follows:
|
You can control which level is enabled as follows:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
wrapper-cache-enabled: true
|
distributions-cache-enabled: true
|
||||||
dependencies-cache-enabled: true
|
dependencies-cache-enabled: true
|
||||||
configuration-cache-enabled: true
|
configuration-cache-enabled: true
|
||||||
```
|
```
|
||||||
|
|
||||||
The wrapper installation cache is simple and can't be configured further.
|
NOTE: The `wrapper-cache-enabled` flag has been deprecated, replaced by `distributions-cache-enabled` which enables caching for all downloaded distributions, including Gradle wrapper downloads.
|
||||||
|
|
||||||
|
The distributions cache is simple and can't be configured further.
|
||||||
|
|
||||||
The dependencies and configuration cache will compute a cache key in a best effort manner.
|
The dependencies and configuration cache will compute a cache key in a best effort manner.
|
||||||
Keep reading to learn how to better control how they work.
|
Keep reading to learn how to better control how they work.
|
||||||
|
@ -20,9 +20,13 @@ inputs:
|
|||||||
arguments:
|
arguments:
|
||||||
description: Gradle command line arguments, see gradle --help
|
description: Gradle command line arguments, see gradle --help
|
||||||
required: false
|
required: false
|
||||||
|
distributions-cache-enabled:
|
||||||
|
description: Whether caching downloaded Gradle distributions is enabled or not, default to 'true'
|
||||||
|
required: false
|
||||||
wrapper-cache-enabled:
|
wrapper-cache-enabled:
|
||||||
description: Whether caching wrapper installation is enabled or not, default to 'true'
|
description: Whether caching wrapper installation is enabled or not, default to 'true'
|
||||||
required: false
|
required: false
|
||||||
|
deprecationMessage: Replaced by 'distributions-cache-enabled' which enables caching for all downloaded Gradle distributions
|
||||||
dependencies-cache-enabled:
|
dependencies-cache-enabled:
|
||||||
description: Whether caching dependencies is enabled or not, default to 'false'
|
description: Whether caching dependencies is enabled or not, default to 'false'
|
||||||
required: false
|
required: false
|
||||||
|
2
dist/main/index.js
vendored
2
dist/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/post/index.js
vendored
2
dist/post/index.js
vendored
File diff suppressed because one or more lines are too long
@ -107,7 +107,16 @@ export function extractGradleWrapperSlugFromDistUri(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isWrapperCacheDisabled(): boolean {
|
function isWrapperCacheDisabled(): boolean {
|
||||||
return !github.inputBoolean('wrapper-cache-enabled', true)
|
// Check if either 'distributions' or 'wrapper' cache has been disabled
|
||||||
|
const wrapperCacheEnabled = github.inputBoolean(
|
||||||
|
'wrapper-cache-enabled',
|
||||||
|
true
|
||||||
|
)
|
||||||
|
const distributionsCacheEnabled = github.inputBoolean(
|
||||||
|
'distributions-cache-enabled',
|
||||||
|
true
|
||||||
|
)
|
||||||
|
return !wrapperCacheEnabled || !distributionsCacheEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCacheKey(wrapperSlug: string): string {
|
function getCacheKey(wrapperSlug: string): string {
|
||||||
|
102
src/provision.ts
102
src/provision.ts
@ -3,9 +3,11 @@ import * as os from 'os'
|
|||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as httpm from '@actions/http-client'
|
import * as httpm from '@actions/http-client'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
|
import * as cache from '@actions/cache'
|
||||||
import * as toolCache from '@actions/tool-cache'
|
import * as toolCache from '@actions/tool-cache'
|
||||||
|
|
||||||
import * as gradlew from './gradlew'
|
import * as gradlew from './gradlew'
|
||||||
|
import * as github from './github-utils'
|
||||||
|
|
||||||
const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'
|
const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'
|
||||||
|
|
||||||
@ -31,7 +33,7 @@ async function gradleCurrent(): Promise<string> {
|
|||||||
const versionInfo = await gradleVersionDeclaration(
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
`${gradleVersionsBaseUrl}/current`
|
`${gradleVersionsBaseUrl}/current`
|
||||||
)
|
)
|
||||||
return provisionGradle(versionInfo.version, versionInfo.downloadUrl)
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gradleReleaseCandidate(): Promise<string> {
|
async function gradleReleaseCandidate(): Promise<string> {
|
||||||
@ -39,7 +41,7 @@ async function gradleReleaseCandidate(): Promise<string> {
|
|||||||
`${gradleVersionsBaseUrl}/release-candidate`
|
`${gradleVersionsBaseUrl}/release-candidate`
|
||||||
)
|
)
|
||||||
if (versionInfo && versionInfo.version && versionInfo.downloadUrl) {
|
if (versionInfo && versionInfo.version && versionInfo.downloadUrl) {
|
||||||
return provisionGradle(versionInfo.version, versionInfo.downloadUrl)
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
core.info('No current release-candidate found, will fallback to current')
|
core.info('No current release-candidate found, will fallback to current')
|
||||||
return gradleCurrent()
|
return gradleCurrent()
|
||||||
@ -49,14 +51,14 @@ async function gradleNightly(): Promise<string> {
|
|||||||
const versionInfo = await gradleVersionDeclaration(
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
`${gradleVersionsBaseUrl}/nightly`
|
`${gradleVersionsBaseUrl}/nightly`
|
||||||
)
|
)
|
||||||
return provisionGradle(versionInfo.version, versionInfo.downloadUrl)
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gradleReleaseNightly(): Promise<string> {
|
async function gradleReleaseNightly(): Promise<string> {
|
||||||
const versionInfo = await gradleVersionDeclaration(
|
const versionInfo = await gradleVersionDeclaration(
|
||||||
`${gradleVersionsBaseUrl}/release-nightly`
|
`${gradleVersionsBaseUrl}/release-nightly`
|
||||||
)
|
)
|
||||||
return provisionGradle(versionInfo.version, versionInfo.downloadUrl)
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gradle(version: string): Promise<string> {
|
async function gradle(version: string): Promise<string> {
|
||||||
@ -64,7 +66,7 @@ async function gradle(version: string): Promise<string> {
|
|||||||
if (!versionInfo) {
|
if (!versionInfo) {
|
||||||
throw new Error(`Gradle version ${version} does not exists`)
|
throw new Error(`Gradle version ${version} does not exists`)
|
||||||
}
|
}
|
||||||
return provisionGradle(versionInfo.version, versionInfo.downloadUrl)
|
return provisionGradle(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gradleVersionDeclaration(
|
async function gradleVersionDeclaration(
|
||||||
@ -84,41 +86,79 @@ async function findGradleVersionDeclaration(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function provisionGradle(version: string, url: string): Promise<string> {
|
async function provisionGradle(
|
||||||
const cachedInstall: string = toolCache.find('gradle', version)
|
versionInfo: GradleVersionInfo
|
||||||
if (cachedInstall.length > 0) {
|
): Promise<string> {
|
||||||
const cachedExecutable = executableFrom(cachedInstall)
|
const installsDir = path.join(os.homedir(), 'gradle-installations/installs')
|
||||||
core.info(`Provisioned Gradle executable ${cachedExecutable}`)
|
const installDir = path.join(installsDir, `gradle-${versionInfo.version}`)
|
||||||
return cachedExecutable
|
if (fs.existsSync(installDir)) {
|
||||||
|
core.info(`Gradle installation already exists at ${installDir}`)
|
||||||
|
return executableFrom(installDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmpdir = path.join(os.homedir(), 'gradle-provision-tmpdir')
|
const downloadPath = await downloadAndCacheGradleDistribution(versionInfo)
|
||||||
|
|
||||||
core.info(`Downloading ${url}`)
|
|
||||||
|
|
||||||
const downloadPath = path.join(
|
|
||||||
tmpdir,
|
|
||||||
`downloads/gradle-${version}-bin.zip`
|
|
||||||
)
|
|
||||||
await toolCache.downloadTool(url, downloadPath)
|
|
||||||
core.info(
|
|
||||||
`Downloaded at ${downloadPath}, size ${fs.statSync(downloadPath).size}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const installsDir = path.join(tmpdir, 'installs')
|
|
||||||
await toolCache.extractZip(downloadPath, installsDir)
|
await toolCache.extractZip(downloadPath, installsDir)
|
||||||
const installDir = path.join(installsDir, `gradle-${version}`)
|
core.info(`Extracted Gradle ${versionInfo.version} to ${installDir}`)
|
||||||
core.info(`Extracted in ${installDir}`)
|
|
||||||
|
|
||||||
const executable = executableFrom(installDir)
|
const executable = executableFrom(installDir)
|
||||||
fs.chmodSync(executable, '755')
|
fs.chmodSync(executable, '755')
|
||||||
core.info(`Provisioned Gradle executable ${executable}`)
|
core.info(`Provisioned Gradle executable ${executable}`)
|
||||||
|
|
||||||
toolCache.cacheDir(installDir, 'gradle', version)
|
|
||||||
|
|
||||||
return executable
|
return executable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function downloadAndCacheGradleDistribution(
|
||||||
|
versionInfo: GradleVersionInfo
|
||||||
|
): Promise<string> {
|
||||||
|
const downloadPath = path.join(
|
||||||
|
os.homedir(),
|
||||||
|
`gradle-installations/downloads/gradle-${versionInfo.version}-bin.zip`
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isDistributionsCacheDisabled()) {
|
||||||
|
await downloadGradleDistribution(versionInfo, downloadPath)
|
||||||
|
return downloadPath
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheKey = `gradle-${versionInfo.version}`
|
||||||
|
const restoreKey = await cache.restoreCache([downloadPath], cacheKey)
|
||||||
|
if (restoreKey) {
|
||||||
|
core.info(
|
||||||
|
`Restored Gradle distribution ${cacheKey} from cache to ${downloadPath}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
core.info(
|
||||||
|
`Gradle distribution ${versionInfo.version} not found in cache. Will download.`
|
||||||
|
)
|
||||||
|
await downloadGradleDistribution(versionInfo, downloadPath)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await cache.saveCache([downloadPath], cacheKey)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error
|
||||||
|
} else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message)
|
||||||
|
} else {
|
||||||
|
core.info(`[warning] ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return downloadPath
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadGradleDistribution(
|
||||||
|
versionInfo: GradleVersionInfo,
|
||||||
|
downloadPath: string
|
||||||
|
): Promise<void> {
|
||||||
|
await toolCache.downloadTool(versionInfo.downloadUrl, downloadPath)
|
||||||
|
core.info(
|
||||||
|
`Downloaded ${versionInfo.downloadUrl} to ${downloadPath} (size ${
|
||||||
|
fs.statSync(downloadPath).size
|
||||||
|
})`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function executableFrom(installDir: string): string {
|
function executableFrom(installDir: string): string {
|
||||||
return path.join(installDir, 'bin', `${gradlew.installScriptFilename()}`)
|
return path.join(installDir, 'bin', `${gradlew.installScriptFilename()}`)
|
||||||
}
|
}
|
||||||
@ -139,6 +179,10 @@ async function httpGetString(url: string): Promise<string> {
|
|||||||
return response.readBody()
|
return response.readBody()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDistributionsCacheDisabled(): boolean {
|
||||||
|
return !github.inputBoolean('distributions-cache-enabled', true)
|
||||||
|
}
|
||||||
|
|
||||||
interface GradleVersionInfo {
|
interface GradleVersionInfo {
|
||||||
version: string
|
version: string
|
||||||
downloadUrl: string
|
downloadUrl: string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user