Compare commits

..

30 Commits

Author SHA1 Message Date
Daz DeBoer
a94b9252d5 Improve cache logging 2021-10-16 10:15:40 -06:00
Daz DeBoer
25672bf196 Build outputs 2021-10-16 09:50:40 -06:00
Daz DeBoer
cb6a0acca4 Use precise matching for artifact bundles
This should fix the warnings issued when saving artifact bundles.
2021-10-16 09:49:15 -06:00
Daz DeBoer
aa2ed2e033 Use cache protocol version for bundle keys too 2021-10-16 09:49:14 -06:00
Daz DeBoer
263f84178a Prefix cache key with protocol version
This will ensure that incompatiblee cache entries generated by previous action releases
will not be used.
2021-10-16 08:33:42 -06:00
Daz DeBoer
0eb5996567 Merge pull request #93 from gradle/dd/instrumented-jars-fix
Ensure all-or-nothing restore of cached instrumented-jars

Leaving the .lock and .receipt files lying around was causing issues when the actual jar files were not restored. Now the entire directory will either be missing, or completely restored.

Fixes #91
2021-10-15 23:04:47 +02:00
Daz DeBoer
fe55bf4667 Build outputs 2021-10-15 14:56:44 -06:00
Daz DeBoer
709ded51a5 Treat directory for instrumented jar as single artifact
Leaving the `.lock` and `.receipt` files lying around was causing
issues when the actual jar files were not restored. Now the entire
directory will either be missing, or completely restored.
2021-10-15 14:54:29 -06:00
Daz DeBoer
8b1f1a3817 Add test for execution when no bundles are restored 2021-10-15 13:29:09 -06:00
Daz DeBoer
7abf13ee48 Build outputs 2021-10-15 13:21:26 -06:00
Daz DeBoer
da64595ccc Make artifact bundle definitions an input parameter 2021-10-15 13:21:13 -06:00
Daz DeBoer
29b14c7fca Refactor: rename methods for 'bundle' concept 2021-10-15 12:34:38 -06:00
Daz DeBoer
d1ab42cddf Document support for multi-line arguments
Fixes #88
2021-10-15 12:24:41 -06:00
Daz DeBoer
422726cec5 Add test for multi-line input arguments 2021-10-15 12:20:01 -06:00
Daz DeBoer
4bc52c85c3 Merge pull request #92 from gradle/dd/cache-debug-logging
Improve cache logging and behaviour
2021-10-15 20:17:35 +02:00
Daz DeBoer
e7b5fd0b28 Build outputs 2021-10-15 11:46:51 -06:00
Daz DeBoer
53ccc3e0d7 Add more cache debug logging 2021-10-15 11:45:15 -06:00
Daz DeBoer
8ab7c9d8dd Do not fail action on cache errors
Ensure that we catch and log errors in `beforeSave` and `afterRestore`,
and do not fail the entire workflow in these cases.
2021-10-14 12:19:24 -06:00
Daz DeBoer
0cf00ed767 Fix test for release-candidate
Since this is an ever-changing version, this fix removes the `gradleVersionCheck` from the invocation.
2021-10-14 10:48:44 -06:00
Daz DeBoer
aedc5fc8f9 Mention that CACHE_DEBUG_ENABLED will disable parallel save/restore 2021-10-14 10:41:45 -06:00
Daz DeBoer
78e25cd233 Document the CACHE_DEBUG_ENABLED flag 2021-10-14 10:39:12 -06:00
Daz DeBoer
29894757f3 Merge pull request #90 from gradle/dd/windows-locks
Allow time for processes to delete file locks on windows
2021-10-05 01:30:13 +02:00
Daz DeBoer
5328161026 Build outputs 2021-10-04 23:59:42 +02:00
Daz DeBoer
4968d2280b Allow time for processes to release file locks on windows 2021-10-04 23:59:08 +02:00
Daz DeBoer
c000a0b58f Merge pull request #87 from gradle/dd/gradle-versions
Fix build-scan link detection with older build-scan plugins

Fixes #86
2021-09-29 15:15:24 -06:00
Daz DeBoer
6ff498182a Add checks for build scan links 2021-09-29 15:10:39 -06:00
Daz DeBoer
60b1ffac6b Fix build-scan-init script to work with build-in build-scan plugins 2021-09-29 14:39:48 -06:00
Daz DeBoer
9b7c81f8f6 Test execution with older Gradle versions 2021-09-29 13:34:05 -06:00
Daz DeBoer
b650771559 Cleanup samples 2021-09-29 13:23:25 -06:00
Daz DeBoer
17f624cb5b Rename 'basic' sample to 'groovy-dsl' 2021-09-28 20:31:11 -06:00
32 changed files with 349 additions and 138 deletions

View File

@@ -0,0 +1,27 @@
name: Test different action inputs
on:
pull_request:
push:
workflow_dispatch:
env:
CACHE_KEY_PREFIX: ${{github.workflow}}#${{github.run_number}}-
jobs:
action-inputs:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Invoke with multi-line arguments
uses: ./
with:
build-root-directory: __tests__/samples/groovy-dsl
arguments: |
--configuration-cache
--build-cache
-DsystemProperty=FOO
-PgradleProperty=BAR
test
jar

View File

@@ -22,12 +22,12 @@ jobs:
- name: Build using Gradle wrapper
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test
- name: Build with configuration-cache enabled
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test --configuration-cache
# Test that the gradle-user-home cache will cache dependencies, by running build with --offline
@@ -43,7 +43,7 @@ jobs:
- name: Execute Gradle build with --offline
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test --offline
cache-read-only: true
@@ -60,7 +60,7 @@ jobs:
- name: Execute Gradle build and verify tasks from cache
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test -DverifyCachedBuild=true
cache-read-only: true
@@ -79,6 +79,22 @@ jobs:
env:
VERIFY_CACHED_CONFIGURATION: true
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test --configuration-cache
cache-read-only: true
# Check that the build can run when no bundles are restored
no-bundles-restored:
needs: seed-build
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Execute Gradle build with no cache artifact bundles restored
uses: ./
with:
build-root-directory: __tests__/samples/groovy-dsl
arguments: test
cache-artifact-bundles: '[]'
cache-read-only: true

View File

@@ -33,10 +33,75 @@ jobs:
with:
gradle-version: release-candidate
build-root-directory: __tests__/samples/no-wrapper
arguments: help -DgradleVersionCheck=7.2
arguments: help
- name: Test use defined Gradle executable
uses: ./
with:
gradle-executable: __tests__/samples/basic/gradlew${{ matrix.script-suffix }}
gradle-executable: __tests__/samples/groovy-dsl/gradlew${{ matrix.script-suffix }}
build-root-directory: __tests__/samples/no-wrapper
arguments: help -DgradleVersionCheck=7.1.1
arguments: help -DgradleVersionCheck=7.1.1
gradle-versions:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: windows-latest
script-suffix: '.bat'
runs-on: ${{ matrix.os }}
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Test Gradle 7
uses: ./
id: gradle7
with:
gradle-version: 7.2
build-root-directory: __tests__/samples/no-wrapper
arguments: help -DgradleVersionCheck=7.2
- name: Check Gradle 7 scan
if: ${{ !steps.gradle7.outputs.build-scan-url }}
uses: actions/github-script@v3
with:
script: |
core.setFailed('No build scan detected')
- name: Test Gradle 6
uses: ./
id: gradle6
with:
gradle-version: 6.9
build-root-directory: __tests__/samples/no-wrapper
arguments: help -DgradleVersionCheck=6.9
- name: Check Gradle 6 scan
if: ${{ !steps.gradle6.outputs.build-scan-url }}
uses: actions/github-script@v3
with:
script: |
core.setFailed('No build scan detected')
- name: Test Gradle 5
uses: ./
id: gradle5
with:
gradle-version: 5.6.4
build-root-directory: __tests__/samples/no-wrapper-gradle-5
arguments: help -DgradleVersionCheck=5.6.4
- name: Check Gradle 5 scan
if: ${{ !steps.gradle5.outputs.build-scan-url }}
uses: actions/github-script@v3
with:
script: |
core.setFailed('No build scan detected')
- name: Test Gradle 4
uses: ./
id: gradle4
with:
gradle-version: 4.10.3
build-root-directory: __tests__/samples/no-wrapper-gradle-4
arguments: help -DgradleVersionCheck=4.10.3
- name: Check Gradle 4 scan
if: ${{ !steps.gradle4.outputs.build-scan-url }}
uses: actions/github-script@v3
with:
script: |
core.setFailed('No build scan detected')

View File

@@ -20,7 +20,7 @@ jobs:
- name: Build using Gradle wrapper
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test
# Test that the gradle-user-home cache will cache dependencies, by running build with --offline
@@ -33,7 +33,7 @@ jobs:
- name: Execute Gradle build with --offline
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test --offline
cache-read-only: true
@@ -47,6 +47,6 @@ jobs:
- name: Execute Gradle build and verify tasks from cache
uses: ./
with:
build-root-directory: __tests__/samples/basic
build-root-directory: __tests__/samples/groovy-dsl
arguments: test -DverifyCachedBuild=true
cache-read-only: true

View File

@@ -47,6 +47,7 @@ Each invocation will start its run with the filesystem state remaining from the
### Command-line arguments
The `arguments` input can used to pass arbitrary arguments to the `gradle` command line.
Arguments can be supplied in a single line, or as a multi-line input.
Here are some valid examples:
```yaml
@@ -54,8 +55,11 @@ arguments: build
arguments: check --scan
arguments: some arbitrary tasks
arguments: build -PgradleProperty=foo
arguments: build -DsystemProperty=bar
....
arguments: |
build
--scan
-PgradleProperty=foo
-DsystemProperty=bar
```
See `gradle --help` for more information.
@@ -182,6 +186,17 @@ You can enable read-only caching for any of the caches as follows:
cache-read-only: true
```
### Cache debugging
It is possible to enable additional debug logging for cache operations. You do via the `CACHE_DEBUG_ENABLED` environment variable:
```yaml
env:
CACHE_DEBUG_ENABLED: true
```
Note that this setting will also prevent certain cache operations from running in parallel, further assisting with debugging.
## Build scans
If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-build-action` action will:

View File

@@ -1,6 +0,0 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

View File

@@ -1,6 +0,0 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

View File

@@ -1,5 +0,0 @@
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build

View File

@@ -0,0 +1,10 @@
plugins {
id "com.gradle.build-scan" version "1.16"
}
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
publishAlways()
}

View File

@@ -0,0 +1,8 @@
rootProject.name = 'no-wrapper'
println "Using Gradle version: ${gradle.gradleVersion}"
def gradleVersionCheck = System.properties.gradleVersionCheck
if (gradleVersionCheck && gradle.gradleVersion != gradleVersionCheck) {
throw new RuntimeException("Got the wrong version: expected ${gradleVersionCheck} but was ${gradle.gradleVersion}")
}

View File

@@ -0,0 +1,12 @@
plugins {
id("com.gradle.build-scan") version("3.7")
}
gradleEnterprise {
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
publishAlways()
uploadInBackground = false
}
}

View File

@@ -0,0 +1,8 @@
rootProject.name = 'no-wrapper'
println "Using Gradle version: ${gradle.gradleVersion}"
def gradleVersionCheck = System.properties.gradleVersionCheck
if (gradleVersionCheck && gradle.gradleVersion != gradleVersionCheck) {
throw new RuntimeException("Got the wrong version: expected ${gradleVersionCheck} but was ${gradle.gradleVersion}")
}

View File

@@ -1,6 +0,0 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

View File

@@ -1,5 +0,0 @@
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build

View File

@@ -14,7 +14,7 @@ inputs:
description: Path to the root directory of the build
required: false
arguments:
description: Gradle command line arguments, see gradle --help
description: Gradle command line arguments (supports multi-line input)
required: false
cache-disabled:
description: When 'true', all caching is disabled. No entries will be written to or read from the cache.
@@ -30,6 +30,16 @@ inputs:
description: Used to uniquely identify the current job invocation. Defaults to the matrix values for this job; this should not be overridden by users.
required: false
default: ${{ toJSON(matrix) }}
cache-artifact-bundles:
description: Names and patterns of artifact bundles to cache separately. For internal use only.
required: false
default: |
[
["generated-gradle-jars", "caches/*/generated-gradle-jars/*.jar"],
["wrapper-zips", "wrapper/dists/*/*/*.zip"],
["dependency-jars", "caches/modules-*/files-*/**/*.jar"],
["instrumented-jars", "caches/jars-*/*/"]
]
outputs:
build-scan-url:

2
dist/main/index.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/post/index.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -18,31 +18,29 @@ import org.gradle.util.GradleVersion
def isTopLevelBuild = gradle.getParent() == null
if (isTopLevelBuild) {
def version = GradleVersion.current().baseVersion
def atLeastGradle5 = version >= GradleVersion.version("5.0")
def atLeastGradle4 = version >= GradleVersion.version("4.0")
def atLeastGradle6 = version >= GradleVersion.version("6.0")
if (atLeastGradle6) {
settingsEvaluated { settings ->
if (settings.pluginManager.hasPlugin("com.gradle.enterprise")) {
registerCallbacks(settings.extensions["gradleEnterprise"], settings.rootProject.name)
registerCallbacks(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject.name)
}
}
} else if (atLeastGradle5) {
} else if (atLeastGradle4) {
projectsEvaluated { gradle ->
if (gradle.rootProject.pluginManager.hasPlugin("com.gradle.build-scan")) {
registerCallbacks(gradle.rootProject.extensions["gradleEnterprise"], gradle.rootProject.name)
registerCallbacks(gradle.rootProject.extensions["buildScan"], gradle.rootProject.name)
}
}
}
}
def registerCallbacks(gradleEnterprise, rootProjectName) {
gradleEnterprise.with {
buildScan {
def scanFile = new File("gradle-build-scan.txt")
buildScanPublished { buildScan ->
scanFile.text = buildScan.buildScanUri
}
def registerCallbacks(buildScanExtension, rootProjectName) {
buildScanExtension.with {
def scanFile = new File("gradle-build-scan.txt")
buildScanPublished { buildScan ->
scanFile.text = buildScan.buildScanUri
}
}
}

View File

@@ -5,18 +5,16 @@ import * as core from '@actions/core'
import * as glob from '@actions/glob'
import * as exec from '@actions/exec'
import {AbstractCache, hashFileNames} from './cache-utils'
import {
AbstractCache,
getCacheKeyPrefix,
hashFileNames,
tryDelete
} from './cache-utils'
// Which paths under Gradle User Home should be cached
const CACHE_PATH = ['caches', 'notifications']
const COMMON_ARTIFACT_CACHES = new Map([
['generated-gradle-jars', 'caches/*/generated-gradle-jars/*.jar'],
['wrapper-zips', 'wrapper/dists/*/*/*.zip'],
['dependency-jars', 'caches/modules-*/files-*/**/*.jar'],
['instrumented-jars', 'caches/jars-*/*/*.jar']
])
export class GradleUserHomeCache extends AbstractCache {
private gradleUserHome: string
@@ -26,15 +24,15 @@ export class GradleUserHomeCache extends AbstractCache {
}
async afterRestore(): Promise<void> {
await this.reportCacheEntrySize('as restored from cache')
await this.restoreCommonArtifacts()
await this.reportCacheEntrySize('after restoring common artifacts')
await this.reportGradleUserHomeSize('as restored from cache')
await this.restoreArtifactBundles()
await this.reportGradleUserHomeSize('after restoring common artifacts')
}
private async restoreCommonArtifacts(): Promise<void> {
private async restoreArtifactBundles(): Promise<void> {
const processes: Promise<void>[] = []
for (const [bundle, pattern] of this.getCommonArtifactPaths()) {
const p = this.restoreCommonArtifactBundle(bundle, pattern)
for (const [bundle, pattern] of this.getArtifactBundles()) {
const p = this.restoreArtifactBundle(bundle, pattern)
// Run sequentially when debugging enabled
if (this.cacheDebuggingEnabled) {
await p
@@ -45,13 +43,13 @@ export class GradleUserHomeCache extends AbstractCache {
await Promise.all(processes)
}
private async restoreCommonArtifactBundle(
private async restoreArtifactBundle(
bundle: string,
artifactPath: string
): Promise<void> {
const cacheMetaFile = this.getCacheMetaFile(bundle)
if (fs.existsSync(cacheMetaFile)) {
const cacheKey = fs.readFileSync(cacheMetaFile, 'utf-8').trim()
const bundleMetaFile = this.getBundleMetaFile(bundle)
if (fs.existsSync(bundleMetaFile)) {
const cacheKey = fs.readFileSync(bundleMetaFile, 'utf-8').trim()
const restoreKey = await this.restoreCache([artifactPath], cacheKey)
if (restoreKey) {
core.info(
@@ -59,17 +57,17 @@ export class GradleUserHomeCache extends AbstractCache {
)
} else {
this.debug(
`Failed to restore ${bundle} with key ${cacheKey} to ${artifactPath}`
`Did not restore ${bundle} with key ${cacheKey} to ${artifactPath}`
)
}
} else {
this.debug(
`No metafile found to restore ${bundle}: ${cacheMetaFile}`
`No metafile found to restore ${bundle}: ${bundleMetaFile}`
)
}
}
private getCacheMetaFile(name: string): string {
private getBundleMetaFile(name: string): string {
return path.resolve(
this.gradleUserHome,
'caches',
@@ -77,47 +75,18 @@ export class GradleUserHomeCache extends AbstractCache {
)
}
private async reportCacheEntrySize(label: string): Promise<void> {
if (!this.cacheDebuggingEnabled) {
return
}
if (!fs.existsSync(this.gradleUserHome)) {
return
}
const result = await exec.getExecOutput(
'du',
['-h', '-c', '-t', '5M'],
{
cwd: this.gradleUserHome,
silent: true,
ignoreReturnCode: true
}
)
core.info(`Gradle User Home cache entry (directories >5M): ${label}`)
core.info(
result.stdout
.trimEnd()
.replace(/\t/g, ' ')
.split('\n')
.map(it => {
return ` ${it}`
})
.join('\n')
)
core.info('-----------------------')
}
async beforeSave(): Promise<void> {
await this.saveCommonArtifacts()
await this.reportGradleUserHomeSize('before saving common artifacts')
await this.saveArtifactBundles()
await this.reportGradleUserHomeSize(
'after saving common artifacts (./wrapper dir is not cached)'
)
}
private async saveCommonArtifacts(): Promise<void> {
private async saveArtifactBundles(): Promise<void> {
const processes: Promise<void>[] = []
for (const [bundle, pattern] of this.getCommonArtifactPaths()) {
const p = this.saveCommonArtifactBundle(bundle, pattern)
for (const [bundle, pattern] of this.getArtifactBundles()) {
const p = this.saveArtifactBundle(bundle, pattern)
// Run sequentially when debugging enabled
if (this.cacheDebuggingEnabled) {
await p
@@ -128,28 +97,31 @@ export class GradleUserHomeCache extends AbstractCache {
await Promise.all(processes)
}
private async saveCommonArtifactBundle(
private async saveArtifactBundle(
bundle: string,
artifactPath: string
): Promise<void> {
const cacheMetaFile = this.getCacheMetaFile(bundle)
const bundleMetaFile = this.getBundleMetaFile(bundle)
const globber = await glob.create(artifactPath)
const commonArtifactFiles = await globber.glob()
const globber = await glob.create(artifactPath, {
implicitDescendants: false,
followSymbolicLinks: false
})
const bundleFiles = await globber.glob()
// Handle no matching files
if (commonArtifactFiles.length === 0) {
if (bundleFiles.length === 0) {
this.debug(`No files found to cache for ${bundle}`)
if (fs.existsSync(cacheMetaFile)) {
fs.unlinkSync(cacheMetaFile)
if (fs.existsSync(bundleMetaFile)) {
tryDelete(bundleMetaFile)
}
return
}
const previouslyRestoredKey = fs.existsSync(cacheMetaFile)
? fs.readFileSync(cacheMetaFile, 'utf-8').trim()
const previouslyRestoredKey = fs.existsSync(bundleMetaFile)
? fs.readFileSync(bundleMetaFile, 'utf-8').trim()
: ''
const cacheKey = this.createCacheKey(bundle, commonArtifactFiles)
const cacheKey = this.createCacheKey(bundle, bundleFiles)
if (previouslyRestoredKey === cacheKey) {
this.debug(
@@ -159,22 +131,26 @@ export class GradleUserHomeCache extends AbstractCache {
core.info(`Caching ${bundle} with cache key: ${cacheKey}`)
await this.saveCache([artifactPath], cacheKey)
this.debug(`Writing cache metafile: ${cacheMetaFile}`)
fs.writeFileSync(cacheMetaFile, cacheKey)
this.debug(`Writing cache metafile: ${bundleMetaFile}`)
fs.writeFileSync(bundleMetaFile, cacheKey)
}
for (const file of commonArtifactFiles) {
fs.unlinkSync(file)
for (const file of bundleFiles) {
tryDelete(file)
}
}
protected createCacheKey(bundle: string, files: string[]): string {
const cacheKeyPrefix = process.env['CACHE_KEY_PREFIX'] || ''
const cacheKeyPrefix = getCacheKeyPrefix()
const relativeFiles = files.map(x =>
path.relative(this.gradleUserHome, x)
)
const key = hashFileNames(relativeFiles)
this.debug(
`Generating cache key for ${bundle} from files: ${relativeFiles}`
)
return `${cacheKeyPrefix}${bundle}-${key}`
}
@@ -197,12 +173,50 @@ export class GradleUserHomeCache extends AbstractCache {
return CACHE_PATH.map(x => path.resolve(this.gradleUserHome, x))
}
private getCommonArtifactPaths(): Map<string, string> {
private getArtifactBundles(): Map<string, string> {
const artifactBundleDefinition = core.getInput('cache-artifact-bundles')
this.debug(
`Using artifact bundle definition: ${artifactBundleDefinition}`
)
const artifactBundles = JSON.parse(artifactBundleDefinition)
return new Map(
Array.from(COMMON_ARTIFACT_CACHES, ([key, value]) => [
Array.from(artifactBundles, ([key, value]) => [
key,
path.resolve(this.gradleUserHome, value)
])
)
}
private async reportGradleUserHomeSize(label: string): Promise<void> {
if (!this.cacheDebuggingEnabled) {
return
}
if (!fs.existsSync(this.gradleUserHome)) {
return
}
const result = await exec.getExecOutput(
'du',
['-h', '-c', '-t', '5M'],
{
cwd: this.gradleUserHome,
silent: true,
ignoreReturnCode: true
}
)
core.info(`Gradle User Home (directories >5M): ${label}`)
core.info(
result.stdout
.trimEnd()
.replace(/\t/g, ' ')
.split('\n')
.map(it => {
return ` ${it}`
})
.join('\n')
)
core.info('-----------------------')
}
}

View File

@@ -3,6 +3,7 @@ import * as cache from '@actions/cache'
import * as github from '@actions/github'
import * as crypto from 'crypto'
import * as path from 'path'
import * as fs from 'fs'
export function isCacheDisabled(): boolean {
return core.getBooleanInput('cache-disabled')
@@ -16,9 +17,13 @@ export function isCacheDebuggingEnabled(): boolean {
return process.env['CACHE_DEBUG_ENABLED'] ? true : false
}
export function getCacheKeyPrefix(): string {
// Prefix can be used to force change all cache keys (defaults to cache protocol version)
return process.env['CACHE_KEY_PREFIX'] || 'v2-'
}
function generateCacheKey(cacheName: string): CacheKey {
// Prefix can be used to force change all cache keys
const cacheKeyPrefix = process.env['CACHE_KEY_PREFIX'] || ''
const cacheKeyPrefix = getCacheKeyPrefix()
// At the most general level, share caches for all executions on the same OS
const runnerOs = process.env['RUNNER_OS'] || ''
@@ -60,6 +65,34 @@ export function hashFileNames(fileNames: string[]): string {
)
}
/**
* Attempt to delete a file or directory, waiting to allow locks to be released
*/
export async function tryDelete(file: string): Promise<void> {
const stat = fs.lstatSync(file)
for (let count = 0; count < 3; count++) {
try {
if (stat.isDirectory()) {
fs.rmdirSync(file, {recursive: true})
} else {
fs.unlinkSync(file)
}
return
} catch (error) {
if (count === 2) {
throw error
} else {
core.warning(String(error))
await delay(1000)
}
}
}
}
async function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms))
}
class CacheKey {
key: string
restoreKeys: string[]
@@ -98,6 +131,12 @@ export abstract class AbstractCache {
core.saveState(this.cacheKeyStateKey, cacheKey.key)
this.debug(
`Requesting ${this.cacheDescription} with
key:${cacheKey.key}
restoreKeys:[${cacheKey.restoreKeys}]`
)
const cacheResult = await this.restoreCache(
this.getCachePath(),
cacheKey.key,
@@ -117,7 +156,13 @@ export abstract class AbstractCache {
`Restored ${this.cacheDescription} from cache key: ${cacheResult}`
)
await this.afterRestore()
try {
await this.afterRestore()
} catch (error) {
core.warning(
`Restore ${this.cacheDescription} failed in 'afterRestore': ${error}`
)
}
return
}
@@ -169,7 +214,14 @@ export abstract class AbstractCache {
return
}
await this.beforeSave()
try {
await this.beforeSave()
} catch (error) {
core.warning(
`Save ${this.cacheDescription} failed in 'beforeSave': ${error}`
)
return
}
core.info(
`Caching ${this.cacheDescription} with cache key: ${cacheKey}`

View File

@@ -7,7 +7,9 @@ const BUILD_ROOT_DIR = 'BUILD_ROOT_DIR'
export async function restore(buildRootDirectory: string): Promise<void> {
if (isCacheDisabled()) {
core.debug('Cache read disabled')
core.info(
'Cache is disabled: will not restore state from previous builds.'
)
return
}
@@ -22,7 +24,9 @@ export async function restore(buildRootDirectory: string): Promise<void> {
export async function save(): Promise<void> {
if (isCacheReadOnly()) {
core.debug('Cache is read-only: not saving cache entry')
core.info(
'Cache is read-only: will not save state for use in subsequent builds.'
)
return
}