2023-06-03 15:58:54 -06:00
import * as core from '@actions/core'
2024-04-06 20:37:46 -06:00
import * as github from '@actions/github'
import * as cache from '@actions/cache'
2024-04-09 10:51:09 -06:00
import * as deprecator from './deprecation-collector'
2024-04-06 20:37:46 -06:00
import { SUMMARY_ENV_VAR } from '@actions/core/lib/summary'
2024-04-09 08:46:20 -06:00
import path from 'path'
2023-06-03 15:58:54 -06:00
2024-04-09 14:09:02 -06:00
const ACTION_ID_VAR = 'GRADLE_ACTION_ID'
2024-08-01 09:39:30 -06:00
export const ACTION_METADATA_DIR = '.setup-gradle'
2024-04-06 20:37:46 -06:00
export class DependencyGraphConfig {
2024-04-07 11:54:02 -06:00
getDependencyGraphOption () : DependencyGraphOption {
2024-04-06 20:37:46 -06:00
const val = core . getInput ( 'dependency-graph' )
switch ( val . toLowerCase (). trim ()) {
case 'disabled' :
return DependencyGraphOption . Disabled
case 'generate' :
return DependencyGraphOption . Generate
case 'generate-and-submit' :
return DependencyGraphOption . GenerateAndSubmit
2025-01-21 11:41:58 -07:00
case 'generate-submit-and-upload' :
return DependencyGraphOption . GenerateSubmitAndUpload
2024-04-06 20:37:46 -06:00
case 'generate-and-upload' :
return DependencyGraphOption . GenerateAndUpload
case 'download-and-submit' :
return DependencyGraphOption . DownloadAndSubmit
}
throw TypeError (
2025-01-21 11:41:58 -07:00
`The value ' ${ val } ' is not valid for 'dependency-graph'. Valid values are: [disabled, generate, generate-and-submit, generate-submit-and-upload, generate-and-upload, download-and-submit].`
2024-04-06 20:37:46 -06:00
)
}
2024-04-07 11:54:02 -06:00
getDependencyGraphContinueOnFailure () : boolean {
2024-04-06 20:37:46 -06:00
return getBooleanInput ( 'dependency-graph-continue-on-failure' , true )
}
2024-04-07 11:54:02 -06:00
getArtifactRetentionDays () : number {
2024-04-06 20:37:46 -06:00
const val = core . getInput ( 'artifact-retention-days' )
return parseNumericInput ( 'artifact-retention-days' , val , 0 )
// Zero indicates that the default repository settings should be used
}
getJobCorrelator () : string {
return DependencyGraphConfig . constructJobCorrelator ( github . context . workflow , github . context . job , getJobMatrix ())
}
2024-04-18 13:40:41 -06:00
getReportDirectory () : string {
2024-07-19 16:20:52 -06:00
const param = core . getInput ( 'dependency-graph-report-dir' )
return path . resolve ( getWorkspaceDirectory (), param )
2024-04-18 13:40:41 -06:00
}
2024-07-16 13:45:14 -06:00
getDownloadArtifactName () : string | undefined {
return process . env [ 'DEPENDENCY_GRAPH_DOWNLOAD_ARTIFACT_NAME' ]
}
2024-07-19 17:07:41 -06:00
getExcludeProjects () : string | undefined {
return getOptionalInput ( 'dependency-graph-exclude-projects' )
}
getIncludeProjects () : string | undefined {
return getOptionalInput ( 'dependency-graph-include-projects' )
}
getExcludeConfigurations () : string | undefined {
return getOptionalInput ( 'dependency-graph-exclude-configurations' )
}
getIncludeConfigurations () : string | undefined {
return getOptionalInput ( 'dependency-graph-include-configurations' )
}
2024-04-06 20:37:46 -06:00
static constructJobCorrelator ( workflow : string , jobId : string , matrixJson : string ) : string {
const matrixString = this . describeMatrix ( matrixJson )
const label = matrixString ? ` ${ workflow } - ${ jobId } - ${ matrixString } ` : ` ${ workflow } - ${ jobId } `
return this . sanitize ( label )
}
private static describeMatrix ( matrixJson : string ) : string {
core . debug ( `Got matrix json: ${ matrixJson } ` )
const matrix = JSON . parse ( matrixJson )
if ( matrix ) {
return Object . values ( matrix ). join ( '-' )
}
return ''
}
private static sanitize ( value : string ) : string {
return value
. replace ( /[^a-zA-Z0-9_-\s]/g , '' )
. replace ( /\s+/g , '_' )
. toLowerCase ()
}
2023-06-03 15:58:54 -06:00
}
2024-04-06 20:37:46 -06:00
export enum DependencyGraphOption {
Disabled = 'disabled' ,
Generate = 'generate' ,
GenerateAndSubmit = 'generate-and-submit' ,
2025-01-21 11:41:58 -07:00
GenerateSubmitAndUpload = 'generate-submit-and-upload' ,
2024-04-06 20:37:46 -06:00
GenerateAndUpload = 'generate-and-upload' ,
2024-07-19 15:42:01 -06:00
DownloadAndSubmit = 'download-and-submit'
2023-06-03 15:58:54 -06:00
}
2024-04-06 20:37:46 -06:00
export class CacheConfig {
isCacheDisabled () : boolean {
if ( ! cache . isFeatureAvailable ()) {
return true
}
return getBooleanInput ( 'cache-disabled' )
}
isCacheReadOnly () : boolean {
return ! this . isCacheWriteOnly () && getBooleanInput ( 'cache-read-only' )
}
isCacheWriteOnly () : boolean {
return getBooleanInput ( 'cache-write-only' )
}
isCacheOverwriteExisting () : boolean {
return getBooleanInput ( 'cache-overwrite-existing' )
}
isCacheStrictMatch () : boolean {
return getBooleanInput ( 'gradle-home-cache-strict-match' )
}
isCacheCleanupEnabled () : boolean {
2024-07-17 19:02:31 -06:00
if ( this . isCacheReadOnly ()) {
return false
}
const cleanupOption = this . getCacheCleanupOption ()
return cleanupOption === CacheCleanupOption . Always || cleanupOption === CacheCleanupOption . OnSuccess
}
shouldPerformCacheCleanup ( hasFailure : boolean ) : boolean {
const cleanupOption = this . getCacheCleanupOption ()
if ( cleanupOption === CacheCleanupOption . Always ) {
return true
}
if ( cleanupOption === CacheCleanupOption . OnSuccess ) {
return ! hasFailure
}
return false
}
private getCacheCleanupOption () : CacheCleanupOption {
2024-07-21 13:44:32 -06:00
const legacyVal = getOptionalBooleanInput ( 'gradle-home-cache-cleanup' )
if ( legacyVal !== undefined ) {
deprecator . recordDeprecation (
'The `gradle-home-cache-cleanup` input parameter has been replaced by `cache-cleanup`'
)
return legacyVal ? CacheCleanupOption.Always : CacheCleanupOption.Never
}
2024-07-17 19:02:31 -06:00
const val = core . getInput ( 'cache-cleanup' )
switch ( val . toLowerCase (). trim ()) {
case 'always' :
return CacheCleanupOption . Always
case 'on-success' :
return CacheCleanupOption . OnSuccess
case 'never' :
2024-07-21 13:44:32 -06:00
return CacheCleanupOption . Never
2024-07-17 19:02:31 -06:00
}
throw TypeError (
`The value ' ${ val } ' is not valid for cache-cleanup. Valid values are: [never, always, on-success].`
)
2024-04-06 20:37:46 -06:00
}
getCacheEncryptionKey () : string {
return core . getInput ( 'cache-encryption-key' )
}
getCacheIncludes () : string [] {
return core . getMultilineInput ( 'gradle-home-cache-includes' )
}
getCacheExcludes () : string [] {
return core . getMultilineInput ( 'gradle-home-cache-excludes' )
}
2023-06-03 15:58:54 -06:00
}
2024-07-17 19:02:31 -06:00
export enum CacheCleanupOption {
Never = 'never' ,
OnSuccess = 'on-success' ,
Always = 'always'
}
2024-04-06 20:37:46 -06:00
export class SummaryConfig {
shouldGenerateJobSummary ( hasFailure : boolean ) : boolean {
// Check if Job Summary is supported on this platform
if ( ! process . env [ SUMMARY_ENV_VAR ]) {
return false
}
return this . shouldAddJobSummary ( this . getJobSummaryOption (), hasFailure )
}
shouldAddPRComment ( hasFailure : boolean ) : boolean {
return this . shouldAddJobSummary ( this . getPRCommentOption (), hasFailure )
}
private shouldAddJobSummary ( option : JobSummaryOption , hasFailure : boolean ) : boolean {
switch ( option ) {
case JobSummaryOption.Always :
return true
case JobSummaryOption.Never :
return false
case JobSummaryOption.OnFailure :
return hasFailure
}
}
private getJobSummaryOption () : JobSummaryOption {
return this . parseJobSummaryOption ( 'add-job-summary' )
}
private getPRCommentOption () : JobSummaryOption {
return this . parseJobSummaryOption ( 'add-job-summary-as-pr-comment' )
}
private parseJobSummaryOption ( paramName : string ) : JobSummaryOption {
const val = core . getInput ( paramName )
switch ( val . toLowerCase (). trim ()) {
case 'never' :
return JobSummaryOption . Never
case 'always' :
return JobSummaryOption . Always
case 'on-failure' :
return JobSummaryOption . OnFailure
}
throw TypeError (
`The value ' ${ val } ' is not valid for ${ paramName } . Valid values are: [never, always, on-failure].`
)
}
2023-08-19 13:01:29 -06:00
}
2024-04-06 20:37:46 -06:00
export enum JobSummaryOption {
Never = 'never' ,
Always = 'always' ,
OnFailure = 'on-failure'
2023-06-03 15:58:54 -06:00
}
2024-04-06 20:37:46 -06:00
export class BuildScanConfig {
2024-05-17 23:07:50 +02:00
static DevelocityAccessKeyEnvVar = 'DEVELOCITY_ACCESS_KEY'
static GradleEnterpriseAccessKeyEnvVar = 'GRADLE_ENTERPRISE_ACCESS_KEY'
2024-04-06 20:37:46 -06:00
getBuildScanPublishEnabled () : boolean {
return getBooleanInput ( 'build-scan-publish' ) && this . verifyTermsOfUseAgreement ()
}
2023-06-03 15:58:54 -06:00
2024-04-06 20:37:46 -06:00
getBuildScanTermsOfUseUrl () : string {
2024-07-19 14:56:50 -06:00
return core . getInput ( 'build-scan-terms-of-use-url' )
2024-04-06 20:37:46 -06:00
}
2023-06-03 15:58:54 -06:00
2024-04-06 20:37:46 -06:00
getBuildScanTermsOfUseAgree () : string {
2024-07-19 14:56:50 -06:00
return core . getInput ( 'build-scan-terms-of-use-agree' )
2024-04-06 20:37:46 -06:00
}
2023-12-20 19:02:27 -07:00
2024-05-16 00:49:55 +02:00
getDevelocityAccessKey () : string {
2024-05-17 23:07:50 +02:00
return (
core . getInput ( 'develocity-access-key' ) ||
process . env [ BuildScanConfig . DevelocityAccessKeyEnvVar ] ||
process . env [ BuildScanConfig . GradleEnterpriseAccessKeyEnvVar ] ||
''
)
2024-05-16 00:49:55 +02:00
}
getDevelocityTokenExpiry () : string {
return core . getInput ( 'develocity-token-expiry' )
}
2024-06-13 11:42:47 -07:00
getDevelocityInjectionEnabled () : boolean | undefined {
2024-06-13 12:52:08 -06:00
return getOptionalBooleanInput ( 'develocity-injection-enabled' )
2024-06-13 11:42:47 -07:00
}
getDevelocityUrl () : string {
return core . getInput ( 'develocity-url' )
}
getDevelocityAllowUntrustedServer () : boolean | undefined {
2024-06-13 12:52:08 -06:00
return getOptionalBooleanInput ( 'develocity-allow-untrusted-server' )
2024-06-13 11:42:47 -07:00
}
getDevelocityCaptureFileFingerprints () : boolean | undefined {
2024-06-13 12:52:08 -06:00
return getOptionalBooleanInput ( 'develocity-capture-file-fingerprints' )
2024-06-13 11:42:47 -07:00
}
getDevelocityEnforceUrl () : boolean | undefined {
2024-06-13 12:52:08 -06:00
return getOptionalBooleanInput ( 'develocity-enforce-url' )
2024-06-13 11:42:47 -07:00
}
getDevelocityPluginVersion () : string {
return core . getInput ( 'develocity-plugin-version' )
}
getDevelocityCcudPluginVersion () : string {
return core . getInput ( 'develocity-ccud-plugin-version' )
}
getGradlePluginRepositoryUrl () : string {
return core . getInput ( 'gradle-plugin-repository-url' )
}
getGradlePluginRepositoryUsername () : string {
return core . getInput ( 'gradle-plugin-repository-username' )
}
getGradlePluginRepositoryPassword () : string {
return core . getInput ( 'gradle-plugin-repository-password' )
}
2024-04-06 20:37:46 -06:00
private verifyTermsOfUseAgreement () : boolean {
if (
( this . getBuildScanTermsOfUseUrl () !== 'https://gradle.com/terms-of-service' &&
this . getBuildScanTermsOfUseUrl () !== 'https://gradle.com/help/legal-terms-of-use' ) ||
this . getBuildScanTermsOfUseAgree () !== 'yes'
) {
core . warning (
`Terms of use at 'https://gradle.com/help/legal-terms-of-use' must be agreed in order to publish build scans.`
)
return false
}
return true
}
2023-06-03 15:58:54 -06:00
}
2024-04-09 08:46:20 -06:00
export class GradleExecutionConfig {
getGradleVersion () : string {
return core . getInput ( 'gradle-version' )
}
2023-06-03 15:58:54 -06:00
2024-04-09 08:46:20 -06:00
getBuildRootDirectory () : string {
const baseDirectory = getWorkspaceDirectory ()
const buildRootDirectoryInput = core . getInput ( 'build-root-directory' )
const resolvedBuildRootDirectory =
buildRootDirectoryInput === ''
? path . resolve ( baseDirectory )
: path . resolve ( baseDirectory , buildRootDirectoryInput )
return resolvedBuildRootDirectory
}
2024-04-06 20:37:46 -06:00
2024-04-09 08:46:20 -06:00
getDependencyResolutionTask () : string {
return core . getInput ( 'dependency-resolution-task' ) || ':ForceDependencyResolutionPlugin_resolveAllDependencies'
}
getAdditionalArguments () : string {
return core . getInput ( 'additional-arguments' )
}
2024-07-19 14:56:50 -06:00
verifyNoArguments () : void {
const input = core . getInput ( 'arguments' )
if ( input . length !== 0 ) {
deprecator . failOnUseOfRemovedFeature (
`The 'arguments' parameter is no longer supported for ${ getActionId () } ` ,
'Using the action to execute Gradle via the `arguments` parameter is deprecated'
)
}
}
2023-06-03 15:58:54 -06:00
}
2024-07-31 20:38:10 -06:00
export class WrapperValidationConfig {
doValidateWrappers () : boolean {
return getBooleanInput ( 'validate-wrappers' )
}
allowSnapshotWrappers () : boolean {
return getBooleanInput ( 'allow-snapshot-wrappers' )
}
2024-04-11 11:56:55 -06:00
}
2023-06-03 15:58:54 -06:00
// Internal parameters
2023-07-01 19:00:28 -06:00
export function getJobMatrix () : string {
2023-06-03 15:58:54 -06:00
return core . getInput ( 'workflow-job-context' )
}
export function getGithubToken () : string {
return core . getInput ( 'github-token' , { required : true })
}
2024-04-08 14:04:29 -06:00
export function getWorkspaceDirectory () : string {
return process . env [ `GITHUB_WORKSPACE` ] || ''
}
2024-04-09 14:09:02 -06:00
export function getActionId () : string | undefined {
return process . env [ ACTION_ID_VAR ]
}
export function setActionId ( id : string ) : void {
core . exportVariable ( ACTION_ID_VAR , id )
}
2023-11-09 08:06:31 +01:00
export function parseNumericInput ( paramName : string , paramValue : string , paramDefault : number ) : number {
if ( paramValue . length === 0 ) {
return paramDefault
}
const numericValue = parseInt ( paramValue )
if ( isNaN ( numericValue )) {
throw TypeError ( `The value ' ${ paramValue } ' is not a valid numeric value for ' ${ paramName } '.` )
}
return numericValue
}
2024-07-19 17:07:41 -06:00
function getOptionalInput ( paramName : string ) : string | undefined {
const paramValue = core . getInput ( paramName )
if ( paramValue . length > 0 ) {
return paramValue
}
return undefined
}
2023-06-03 15:58:54 -06:00
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]` )
}
2024-06-13 11:42:47 -07:00
2024-06-13 12:52:08 -06:00
function getOptionalBooleanInput ( paramName : string ) : boolean | undefined {
2024-06-13 11:42:47 -07:00
const paramValue = core . getInput ( paramName )
2024-06-13 12:52:08 -06:00
if ( paramValue === '' ) {
return undefined
2024-06-13 11:42:47 -07:00
}
2024-06-13 12:52:08 -06:00
return getBooleanInput ( paramName )
2024-06-13 11:42:47 -07:00
}