From 07023d3e3ebd5c20f152180e6dc9eb02291199c6 Mon Sep 17 00:00:00 2001 From: daz Date: Sat, 3 Jun 2023 15:58:54 -0600 Subject: [PATCH] Refactor input parameters Moved reading of all input parameters into a common source: `input-params.ts`. This centralized all input parameter reads, and allowed an improved implementation of reading boolean parameters. In particular, the implementation now provides a default value for a boolean input parameter that isn't declared for an action. --- src/cache-base.ts | 7 ++-- src/cache-extract-entries.ts | 14 ++----- src/cache-utils.ts | 24 +++++------ src/input-params.ts | 77 ++++++++++++++++++++++++++++++++++++ src/main.ts | 9 +---- src/provision.ts | 5 ++- src/repository-layout.ts | 4 +- src/setup-gradle.ts | 4 +- 8 files changed, 102 insertions(+), 42 deletions(-) create mode 100644 src/input-params.ts diff --git a/src/cache-base.ts b/src/cache-base.ts index 8bada14..7c5eeff 100644 --- a/src/cache-base.ts +++ b/src/cache-base.ts @@ -2,6 +2,7 @@ import * as core from '@actions/core' import * as exec from '@actions/exec' import path from 'path' import fs from 'fs' +import * as params from './input-params' import {CacheListener} from './cache-reporting' import {saveCache, restoreCache, cacheDebug, isCacheDebuggingEnabled, tryDelete, generateCacheKey} from './cache-utils' import {GradleHomeEntryExtractor} from './cache-extract-entries' @@ -9,8 +10,6 @@ import {GradleHomeEntryExtractor} from './cache-extract-entries' const RESTORED_CACHE_KEY_KEY = 'restored-cache-key' export const META_FILE_DIR = '.gradle-build-action' -const INCLUDE_PATHS_PARAMETER = 'gradle-home-cache-includes' -const EXCLUDE_PATHS_PARAMETER = 'gradle-home-cache-excludes' export class GradleStateCache { private cacheName: string @@ -142,7 +141,7 @@ export class GradleStateCache { * Delete any file paths that are excluded by the `gradle-home-cache-excludes` parameter. */ private deleteExcludedPaths(): void { - const rawPaths: string[] = core.getMultilineInput(EXCLUDE_PATHS_PARAMETER) + const rawPaths: string[] = params.getCacheExcludes() const resolvedPaths = rawPaths.map(x => path.resolve(this.gradleUserHome, x)) for (const p of resolvedPaths) { @@ -157,7 +156,7 @@ export class GradleStateCache { * but this can be overridden by the `gradle-home-cache-includes` parameter. */ protected getCachePath(): string[] { - const rawPaths: string[] = core.getMultilineInput(INCLUDE_PATHS_PARAMETER) + const rawPaths: string[] = params.getCacheIncludes() rawPaths.push(META_FILE_DIR) const resolvedPaths = rawPaths.map(x => this.resolveCachePath(x)) cacheDebug(`Using cache paths: ${resolvedPaths}`) diff --git a/src/cache-extract-entries.ts b/src/cache-extract-entries.ts index d9ebfe0..bd30051 100644 --- a/src/cache-extract-entries.ts +++ b/src/cache-extract-entries.ts @@ -3,17 +3,11 @@ import fs from 'fs' import * as core from '@actions/core' import * as glob from '@actions/glob' +import * as params from './input-params' + import {META_FILE_DIR} from './cache-base' import {CacheEntryListener, CacheListener} from './cache-reporting' -import { - cacheDebug, - getCacheKeyPrefix, - hashFileNames, - isCacheDebuggingEnabled, - restoreCache, - saveCache, - tryDelete -} from './cache-utils' +import {cacheDebug, getCacheKeyPrefix, hashFileNames, restoreCache, saveCache, tryDelete} from './cache-utils' import {loadBuildResults} from './build-results' const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE' @@ -246,7 +240,7 @@ abstract class AbstractEntryExtractor { // Run actions sequentially if debugging is enabled private async awaitForDebugging(p: Promise): Promise { - if (isCacheDebuggingEnabled()) { + if (params.isCacheDebuggingEnabled()) { await p } return p diff --git a/src/cache-utils.ts b/src/cache-utils.ts index 64cd1e6..55bba16 100644 --- a/src/cache-utils.ts +++ b/src/cache-utils.ts @@ -7,18 +7,12 @@ import * as crypto from 'crypto' import * as path from 'path' import * as fs from 'fs' +import * as params from './input-params' + import {CacheEntryListener} from './cache-reporting' const CACHE_PROTOCOL_VERSION = 'v8-' -const JOB_CONTEXT_PARAMETER = 'workflow-job-context' -const CACHE_DISABLED_PARAMETER = 'cache-disabled' -const CACHE_READONLY_PARAMETER = 'cache-read-only' -const CACHE_WRITEONLY_PARAMETER = 'cache-write-only' -const STRICT_CACHE_MATCH_PARAMETER = 'gradle-home-cache-strict-match' -const CACHE_CLEANUP_ENABLED_PARAMETER = 'gradle-home-cache-cleanup' -const CACHE_DEBUG_VAR = 'GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED' - const CACHE_KEY_PREFIX_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX' const CACHE_KEY_OS_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_ENVIRONMENT' const CACHE_KEY_JOB_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB' @@ -32,23 +26,23 @@ export function isCacheDisabled(): boolean { if (!cache.isFeatureAvailable()) { return true } - return core.getBooleanInput(CACHE_DISABLED_PARAMETER) + return params.isCacheDisabled() } export function isCacheReadOnly(): boolean { - return !isCacheWriteOnly() && core.getBooleanInput(CACHE_READONLY_PARAMETER) + return !isCacheWriteOnly() && params.isCacheReadOnly() } export function isCacheWriteOnly(): boolean { - return core.getBooleanInput(CACHE_WRITEONLY_PARAMETER) + return params.isCacheWriteOnly() } export function isCacheDebuggingEnabled(): boolean { - return process.env[CACHE_DEBUG_VAR] ? true : false + return params.isCacheDebuggingEnabled() } export function isCacheCleanupEnabled(): boolean { - return core.getBooleanInput(CACHE_CLEANUP_ENABLED_PARAMETER) + return params.isCacheCleanupEnabled() } /** @@ -97,7 +91,7 @@ export function generateCacheKey(cacheName: string): CacheKey { // Exact match on Git SHA const cacheKey = `${cacheKeyForJobContext}-${getCacheKeyJobExecution()}` - if (core.getBooleanInput(STRICT_CACHE_MATCH_PARAMETER)) { + if (params.isCacheStrictMatch()) { return new CacheKey(cacheKey, [cacheKeyForJobContext]) } @@ -126,7 +120,7 @@ function getCacheKeyJobInstance(): string { // By default, we hash the full `matrix` data for the run, to uniquely identify this job invocation // The only way we can obtain the `matrix` data is via the `workflow-job-context` parameter in action.yml. - const workflowJobContext = core.getInput(JOB_CONTEXT_PARAMETER) + const workflowJobContext = params.getJobContext() return hashStrings([workflowJobContext]) } diff --git a/src/input-params.ts b/src/input-params.ts new file mode 100644 index 0000000..7fb4e0c --- /dev/null +++ b/src/input-params.ts @@ -0,0 +1,77 @@ +import * as core from '@actions/core' +import {parseArgsStringToArgv} from 'string-argv' + +export function isCacheDisabled(): boolean { + return getBooleanInput('cache-disabled') +} + +export function isCacheReadOnly(): boolean { + return getBooleanInput('cache-read-only') +} + +export function isCacheWriteOnly(): boolean { + return getBooleanInput('cache-write-only') +} + +export function isCacheStrictMatch(): boolean { + return getBooleanInput('gradle-home-cache-strict-match') +} + +export function isCacheDebuggingEnabled(): boolean { + return process.env['GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED'] ? true : false +} + +export function isCacheCleanupEnabled(): boolean { + return getBooleanInput('gradle-home-cache-cleanup') +} + +export function getCacheIncludes(): string[] { + return core.getMultilineInput('gradle-home-cache-includes') +} + +export function getCacheExcludes(): string[] { + return core.getMultilineInput('gradle-home-cache-excludes') +} + +export function getBuildRootDirectory(): string { + return core.getInput('build-root-directory') +} + +export function getGradleVersion(): string { + return core.getInput('gradle-version') +} + +export function getGradleExecutable(): string { + return core.getInput('gradle-executable') +} + +export function getArguments(): string[] { + const input = core.getInput('arguments') + return parseArgsStringToArgv(input) +} + +// Internal parameters +export function getJobContext(): string { + return core.getInput('workflow-job-context') +} + +export function getGithubToken(): string { + return core.getInput('github-token', {required: true}) +} + +export function isJobSummaryEnabled(): boolean { + return getBooleanInput('generate-job-summary', true) +} + +function getBooleanInput(paramName: string, paramDefault = false): boolean { + const paramValue = core.getInput(paramName) + switch (paramValue.toLowerCase().trim()) { + case '': + return paramDefault + case 'false': + return false + case 'true': + return true + } + throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`) +} diff --git a/src/main.ts b/src/main.ts index b871db0..e880bf4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,10 @@ import * as core from '@actions/core' -import {parseArgsStringToArgv} from 'string-argv' import * as setupGradle from './setup-gradle' import * as execution from './execution' import * as provisioner from './provision' import * as layout from './repository-layout' +import * as params from './input-params' /** * The main entry point for the action, called by Github Actions for the step. @@ -18,7 +18,7 @@ export async function run(): Promise { const executable = await provisioner.provisionGradle() // Only execute if arguments have been provided - const args: string[] = parseCommandLineArguments() + const args: string[] = params.getArguments() if (args.length > 0) { const buildRootDirectory = layout.buildRootDirectory() await execution.executeGradleBuild(executable, buildRootDirectory, args) @@ -32,8 +32,3 @@ export async function run(): Promise { } run() - -function parseCommandLineArguments(): string[] { - const input = core.getInput('arguments') - return parseArgsStringToArgv(input) -} diff --git a/src/provision.ts b/src/provision.ts index 410a7cf..3d01c0b 100644 --- a/src/provision.ts +++ b/src/provision.ts @@ -7,6 +7,7 @@ import * as cache from '@actions/cache' import * as toolCache from '@actions/tool-cache' import * as gradlew from './gradlew' +import * as params from './input-params' import * as layout from './repository-layout' import {handleCacheFailure, isCacheDisabled, isCacheReadOnly} from './cache-utils' @@ -17,12 +18,12 @@ const gradleVersionsBaseUrl = 'https://services.gradle.org/versions' * @return Installed Gradle executable or undefined if no version configured. */ export async function provisionGradle(): Promise { - const gradleVersion = core.getInput('gradle-version') + const gradleVersion = params.getGradleVersion() if (gradleVersion !== '' && gradleVersion !== 'wrapper') { return addToPath(path.resolve(await installGradle(gradleVersion))) } - const gradleExecutable = core.getInput('gradle-executable') + const gradleExecutable = params.getGradleExecutable() if (gradleExecutable !== '') { const workspaceDirectory = layout.workspaceDirectory() return addToPath(path.resolve(workspaceDirectory, gradleExecutable)) diff --git a/src/repository-layout.ts b/src/repository-layout.ts index a0ac09e..d021828 100644 --- a/src/repository-layout.ts +++ b/src/repository-layout.ts @@ -1,4 +1,4 @@ -import * as core from '@actions/core' +import * as params from './input-params' import * as path from 'path' export function workspaceDirectory(): string { @@ -7,7 +7,7 @@ export function workspaceDirectory(): string { export function buildRootDirectory(): string { const baseDirectory = workspaceDirectory() - const buildRootDirectoryInput = core.getInput('build-root-directory') + const buildRootDirectoryInput = params.getBuildRootDirectory() const resolvedBuildRootDirectory = buildRootDirectoryInput === '' ? path.resolve(baseDirectory) diff --git a/src/setup-gradle.ts b/src/setup-gradle.ts index 79529de..a5f6a89 100644 --- a/src/setup-gradle.ts +++ b/src/setup-gradle.ts @@ -5,6 +5,7 @@ import * as path from 'path' import * as os from 'os' import * as caches from './caches' import * as layout from './repository-layout' +import * as params from './input-params' import {logJobSummary, writeJobSummary} from './job-summary' import {loadBuildResults} from './build-results' @@ -14,7 +15,6 @@ import {DaemonController} from './daemon-controller' const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED' const GRADLE_USER_HOME = 'GRADLE_USER_HOME' const CACHE_LISTENER = 'CACHE_LISTENER' -const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary' export async function setup(): Promise { const gradleUserHome = await determineGradleUserHome() @@ -93,5 +93,5 @@ function shouldGenerateJobSummary(): boolean { return false } - return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER) + return params.isJobSummaryEnabled() }