diff --git a/src/caches.ts b/src/caches.ts index 04f8d22..47afc64 100644 --- a/src/caches.ts +++ b/src/caches.ts @@ -4,7 +4,6 @@ import {logCachingReport, CacheListener} from './cache-reporting' import {GradleStateCache} from './cache-base' const CACHE_RESTORED_VAR = 'GRADLE_BUILD_ACTION_CACHE_RESTORED' -const GRADLE_USER_HOME = 'GRADLE_USER_HOME' const CACHE_LISTENER = 'CACHE_LISTENER' export async function restore(gradleUserHome: string): Promise { @@ -34,8 +33,6 @@ export async function restore(gradleUserHome: string): Promise { gradleStateCache.init() // Mark the state as restored so that post-action will perform save. core.saveState(CACHE_RESTORED_VAR, true) - // Save the Gradle User Home for the post-action step. - core.saveState(GRADLE_USER_HOME, gradleUserHome) if (isCacheWriteOnly()) { core.info('Cache is write-only: will not restore from cache.') @@ -50,7 +47,7 @@ export async function restore(gradleUserHome: string): Promise { }) } -export async function save(): Promise { +export async function save(gradleUserHome: string): Promise { if (!shouldSaveCaches()) { return } @@ -64,7 +61,6 @@ export async function save(): Promise { } await core.group('Caching Gradle state', async () => { - const gradleUserHome = core.getState(GRADLE_USER_HOME) return new GradleStateCache(gradleUserHome).save(cacheListener) }) diff --git a/src/main.ts b/src/main.ts index f82d3f2..e62cc6f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,8 @@ import * as core from '@actions/core' import * as path from 'path' -import * as os from 'os' import {parseArgsStringToArgv} from 'string-argv' -import * as caches from './caches' +import * as setupGradle from './setup-gradle' import * as execution from './execution' import * as provision from './provision' @@ -14,9 +13,8 @@ export async function run(): Promise { try { const workspaceDirectory = process.env[`GITHUB_WORKSPACE`] || '' const buildRootDirectory = resolveBuildRootDirectory(workspaceDirectory) - const gradleUserHome = determineGradleUserHome(buildRootDirectory) - await caches.restore(gradleUserHome) + await setupGradle.setup(buildRootDirectory) const executable = await provisionGradle(workspaceDirectory) // executable will be undefined if using Gradle wrapper @@ -60,15 +58,6 @@ function resolveBuildRootDirectory(baseDirectory: string): string { return resolvedBuildRootDirectory } -function determineGradleUserHome(rootDir: string): string { - const customGradleUserHome = process.env['GRADLE_USER_HOME'] - if (customGradleUserHome) { - return path.resolve(rootDir, customGradleUserHome) - } - - return path.resolve(os.homedir(), '.gradle') -} - function parseCommandLineArguments(): string[] { const input = core.getInput('arguments') return parseArgsStringToArgv(input) diff --git a/src/post.ts b/src/post.ts index f9957d1..d81a8ca 100644 --- a/src/post.ts +++ b/src/post.ts @@ -1,5 +1,5 @@ import * as core from '@actions/core' -import * as caches from './caches' +import * as setupGradle from './setup-gradle' // Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in // @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to @@ -11,14 +11,14 @@ process.on('uncaughtException', e => handleFailure(e)) */ export async function run(): Promise { try { - await caches.save() + await setupGradle.complete() } catch (error) { handleFailure(error) } } function handleFailure(error: unknown): void { - core.warning(`Unhandled error saving cache - job will continue: ${error}`) + core.warning(`Unhandled error in Gradle post-action - job will continue: ${error}`) if (error instanceof Error && error.stack) { core.info(error.stack) } diff --git a/src/setup-gradle.ts b/src/setup-gradle.ts new file mode 100644 index 0000000..dc093e3 --- /dev/null +++ b/src/setup-gradle.ts @@ -0,0 +1,45 @@ +import * as core from '@actions/core' +import * as path from 'path' +import * as os from 'os' +import * as caches from './caches' + +const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED' +const GRADLE_USER_HOME = 'GRADLE_USER_HOME' + +export async function setup(buildRootDirectory: string): Promise { + const gradleUserHome = determineGradleUserHome(buildRootDirectory) + + // Bypass setup on all but first action step in workflow. + if (process.env[GRADLE_SETUP_VAR]) { + core.info('Gradle setup only performed on first gradle-build-action step in workflow.') + return + } + // Record setup complete: visible to all subsequent actions and prevents duplicate setup + core.exportVariable(GRADLE_SETUP_VAR, true) + // Record setup complete: visible in post-action, to control action completion + core.saveState(GRADLE_SETUP_VAR, true) + + // Save the Gradle User Home for use in the post-action step. + core.saveState(GRADLE_USER_HOME, gradleUserHome) + + await caches.restore(gradleUserHome) +} + +export async function complete(): Promise { + if (!core.getState(GRADLE_SETUP_VAR)) { + core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.') + return + } + + const gradleUserHome = core.getState(GRADLE_USER_HOME) + await caches.save(gradleUserHome) +} + +function determineGradleUserHome(rootDir: string): string { + const customGradleUserHome = process.env['GRADLE_USER_HOME'] + if (customGradleUserHome) { + return path.resolve(rootDir, customGradleUserHome) + } + + return path.resolve(os.homedir(), '.gradle') +}