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.
This commit is contained in:
daz 2023-06-03 15:58:54 -06:00
parent c94d573317
commit 07023d3e3e
No known key found for this signature in database
8 changed files with 102 additions and 42 deletions

View File

@ -2,6 +2,7 @@ import * as core from '@actions/core'
import * as exec from '@actions/exec' import * as exec from '@actions/exec'
import path from 'path' import path from 'path'
import fs from 'fs' import fs from 'fs'
import * as params from './input-params'
import {CacheListener} from './cache-reporting' import {CacheListener} from './cache-reporting'
import {saveCache, restoreCache, cacheDebug, isCacheDebuggingEnabled, tryDelete, generateCacheKey} from './cache-utils' import {saveCache, restoreCache, cacheDebug, isCacheDebuggingEnabled, tryDelete, generateCacheKey} from './cache-utils'
import {GradleHomeEntryExtractor} from './cache-extract-entries' import {GradleHomeEntryExtractor} from './cache-extract-entries'
@ -9,8 +10,6 @@ import {GradleHomeEntryExtractor} from './cache-extract-entries'
const RESTORED_CACHE_KEY_KEY = 'restored-cache-key' const RESTORED_CACHE_KEY_KEY = 'restored-cache-key'
export const META_FILE_DIR = '.gradle-build-action' 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 { export class GradleStateCache {
private cacheName: string private cacheName: string
@ -142,7 +141,7 @@ export class GradleStateCache {
* Delete any file paths that are excluded by the `gradle-home-cache-excludes` parameter. * Delete any file paths that are excluded by the `gradle-home-cache-excludes` parameter.
*/ */
private deleteExcludedPaths(): void { 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)) const resolvedPaths = rawPaths.map(x => path.resolve(this.gradleUserHome, x))
for (const p of resolvedPaths) { for (const p of resolvedPaths) {
@ -157,7 +156,7 @@ export class GradleStateCache {
* but this can be overridden by the `gradle-home-cache-includes` parameter. * but this can be overridden by the `gradle-home-cache-includes` parameter.
*/ */
protected getCachePath(): string[] { protected getCachePath(): string[] {
const rawPaths: string[] = core.getMultilineInput(INCLUDE_PATHS_PARAMETER) const rawPaths: string[] = params.getCacheIncludes()
rawPaths.push(META_FILE_DIR) rawPaths.push(META_FILE_DIR)
const resolvedPaths = rawPaths.map(x => this.resolveCachePath(x)) const resolvedPaths = rawPaths.map(x => this.resolveCachePath(x))
cacheDebug(`Using cache paths: ${resolvedPaths}`) cacheDebug(`Using cache paths: ${resolvedPaths}`)

View File

@ -3,17 +3,11 @@ import fs from 'fs'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as glob from '@actions/glob' import * as glob from '@actions/glob'
import * as params from './input-params'
import {META_FILE_DIR} from './cache-base' import {META_FILE_DIR} from './cache-base'
import {CacheEntryListener, CacheListener} from './cache-reporting' import {CacheEntryListener, CacheListener} from './cache-reporting'
import { import {cacheDebug, getCacheKeyPrefix, hashFileNames, restoreCache, saveCache, tryDelete} from './cache-utils'
cacheDebug,
getCacheKeyPrefix,
hashFileNames,
isCacheDebuggingEnabled,
restoreCache,
saveCache,
tryDelete
} from './cache-utils'
import {loadBuildResults} from './build-results' import {loadBuildResults} from './build-results'
const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE' const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE'
@ -246,7 +240,7 @@ abstract class AbstractEntryExtractor {
// Run actions sequentially if debugging is enabled // Run actions sequentially if debugging is enabled
private async awaitForDebugging(p: Promise<ExtractedCacheEntry>): Promise<ExtractedCacheEntry> { private async awaitForDebugging(p: Promise<ExtractedCacheEntry>): Promise<ExtractedCacheEntry> {
if (isCacheDebuggingEnabled()) { if (params.isCacheDebuggingEnabled()) {
await p await p
} }
return p return p

View File

@ -7,18 +7,12 @@ import * as crypto from 'crypto'
import * as path from 'path' import * as path from 'path'
import * as fs from 'fs' import * as fs from 'fs'
import * as params from './input-params'
import {CacheEntryListener} from './cache-reporting' import {CacheEntryListener} from './cache-reporting'
const CACHE_PROTOCOL_VERSION = 'v8-' 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_PREFIX_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX'
const CACHE_KEY_OS_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_ENVIRONMENT' const CACHE_KEY_OS_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_ENVIRONMENT'
const CACHE_KEY_JOB_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB' const CACHE_KEY_JOB_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB'
@ -32,23 +26,23 @@ export function isCacheDisabled(): boolean {
if (!cache.isFeatureAvailable()) { if (!cache.isFeatureAvailable()) {
return true return true
} }
return core.getBooleanInput(CACHE_DISABLED_PARAMETER) return params.isCacheDisabled()
} }
export function isCacheReadOnly(): boolean { export function isCacheReadOnly(): boolean {
return !isCacheWriteOnly() && core.getBooleanInput(CACHE_READONLY_PARAMETER) return !isCacheWriteOnly() && params.isCacheReadOnly()
} }
export function isCacheWriteOnly(): boolean { export function isCacheWriteOnly(): boolean {
return core.getBooleanInput(CACHE_WRITEONLY_PARAMETER) return params.isCacheWriteOnly()
} }
export function isCacheDebuggingEnabled(): boolean { export function isCacheDebuggingEnabled(): boolean {
return process.env[CACHE_DEBUG_VAR] ? true : false return params.isCacheDebuggingEnabled()
} }
export function isCacheCleanupEnabled(): boolean { 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 // Exact match on Git SHA
const cacheKey = `${cacheKeyForJobContext}-${getCacheKeyJobExecution()}` const cacheKey = `${cacheKeyForJobContext}-${getCacheKeyJobExecution()}`
if (core.getBooleanInput(STRICT_CACHE_MATCH_PARAMETER)) { if (params.isCacheStrictMatch()) {
return new CacheKey(cacheKey, [cacheKeyForJobContext]) 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 // 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. // 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]) return hashStrings([workflowJobContext])
} }

77
src/input-params.ts Normal file
View File

@ -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]`)
}

View File

@ -1,10 +1,10 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {parseArgsStringToArgv} from 'string-argv'
import * as setupGradle from './setup-gradle' import * as setupGradle from './setup-gradle'
import * as execution from './execution' import * as execution from './execution'
import * as provisioner from './provision' import * as provisioner from './provision'
import * as layout from './repository-layout' 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. * The main entry point for the action, called by Github Actions for the step.
@ -18,7 +18,7 @@ export async function run(): Promise<void> {
const executable = await provisioner.provisionGradle() const executable = await provisioner.provisionGradle()
// Only execute if arguments have been provided // Only execute if arguments have been provided
const args: string[] = parseCommandLineArguments() const args: string[] = params.getArguments()
if (args.length > 0) { if (args.length > 0) {
const buildRootDirectory = layout.buildRootDirectory() const buildRootDirectory = layout.buildRootDirectory()
await execution.executeGradleBuild(executable, buildRootDirectory, args) await execution.executeGradleBuild(executable, buildRootDirectory, args)
@ -32,8 +32,3 @@ export async function run(): Promise<void> {
} }
run() run()
function parseCommandLineArguments(): string[] {
const input = core.getInput('arguments')
return parseArgsStringToArgv(input)
}

View File

@ -7,6 +7,7 @@ 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 params from './input-params'
import * as layout from './repository-layout' import * as layout from './repository-layout'
import {handleCacheFailure, isCacheDisabled, isCacheReadOnly} from './cache-utils' 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. * @return Installed Gradle executable or undefined if no version configured.
*/ */
export async function provisionGradle(): Promise<string | undefined> { export async function provisionGradle(): Promise<string | undefined> {
const gradleVersion = core.getInput('gradle-version') const gradleVersion = params.getGradleVersion()
if (gradleVersion !== '' && gradleVersion !== 'wrapper') { if (gradleVersion !== '' && gradleVersion !== 'wrapper') {
return addToPath(path.resolve(await installGradle(gradleVersion))) return addToPath(path.resolve(await installGradle(gradleVersion)))
} }
const gradleExecutable = core.getInput('gradle-executable') const gradleExecutable = params.getGradleExecutable()
if (gradleExecutable !== '') { if (gradleExecutable !== '') {
const workspaceDirectory = layout.workspaceDirectory() const workspaceDirectory = layout.workspaceDirectory()
return addToPath(path.resolve(workspaceDirectory, gradleExecutable)) return addToPath(path.resolve(workspaceDirectory, gradleExecutable))

View File

@ -1,4 +1,4 @@
import * as core from '@actions/core' import * as params from './input-params'
import * as path from 'path' import * as path from 'path'
export function workspaceDirectory(): string { export function workspaceDirectory(): string {
@ -7,7 +7,7 @@ export function workspaceDirectory(): string {
export function buildRootDirectory(): string { export function buildRootDirectory(): string {
const baseDirectory = workspaceDirectory() const baseDirectory = workspaceDirectory()
const buildRootDirectoryInput = core.getInput('build-root-directory') const buildRootDirectoryInput = params.getBuildRootDirectory()
const resolvedBuildRootDirectory = const resolvedBuildRootDirectory =
buildRootDirectoryInput === '' buildRootDirectoryInput === ''
? path.resolve(baseDirectory) ? path.resolve(baseDirectory)

View File

@ -5,6 +5,7 @@ import * as path from 'path'
import * as os from 'os' import * as os from 'os'
import * as caches from './caches' import * as caches from './caches'
import * as layout from './repository-layout' import * as layout from './repository-layout'
import * as params from './input-params'
import {logJobSummary, writeJobSummary} from './job-summary' import {logJobSummary, writeJobSummary} from './job-summary'
import {loadBuildResults} from './build-results' 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_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED'
const GRADLE_USER_HOME = 'GRADLE_USER_HOME' const GRADLE_USER_HOME = 'GRADLE_USER_HOME'
const CACHE_LISTENER = 'CACHE_LISTENER' const CACHE_LISTENER = 'CACHE_LISTENER'
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary'
export async function setup(): Promise<void> { export async function setup(): Promise<void> {
const gradleUserHome = await determineGradleUserHome() const gradleUserHome = await determineGradleUserHome()
@ -93,5 +93,5 @@ function shouldGenerateJobSummary(): boolean {
return false return false
} }
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER) return params.isJobSummaryEnabled()
} }