mirror of
				https://hub.gitmirror.com/https://github.com/gradle/gradle-build-action
				synced 2025-10-31 01:50:08 +08:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "main" and "v2.3.0-beta.1" have entirely different histories.
		
	
	
		
			main
			...
			v2.3.0-bet
		
	
		
							
								
								
									
										3
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | dist/ | ||||||
|  | lib/ | ||||||
|  | node_modules/ | ||||||
							
								
								
									
										54
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | { | ||||||
|  |     "plugins": ["jest", "@typescript-eslint"], | ||||||
|  |     "extends": ["plugin:github/recommended"], | ||||||
|  |     "parser": "@typescript-eslint/parser", | ||||||
|  |     "parserOptions": { | ||||||
|  |       "ecmaVersion": 9, | ||||||
|  |       "sourceType": "module", | ||||||
|  |       "project": "./tsconfig.json" | ||||||
|  |     }, | ||||||
|  |     "rules": { | ||||||
|  |       "eslint-comments/no-use": "off", | ||||||
|  |       "import/no-namespace": "off", | ||||||
|  |       "i18n-text/no-en": "off", | ||||||
|  |       "no-unused-vars": "off", | ||||||
|  |       "sort-imports": "off", | ||||||
|  |       "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], | ||||||
|  |       "@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}], | ||||||
|  |       "@typescript-eslint/no-require-imports": "error", | ||||||
|  |       "@typescript-eslint/array-type": "error", | ||||||
|  |       "@typescript-eslint/await-thenable": "error", | ||||||
|  |       "camelcase": "off", | ||||||
|  |       "@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}], | ||||||
|  |       "@typescript-eslint/func-call-spacing": ["error", "never"], | ||||||
|  |       "@typescript-eslint/no-array-constructor": "error", | ||||||
|  |       "@typescript-eslint/no-empty-interface": "error", | ||||||
|  |       "@typescript-eslint/no-explicit-any": "error", | ||||||
|  |       "@typescript-eslint/no-extraneous-class": "error", | ||||||
|  |       "@typescript-eslint/no-for-in-array": "error", | ||||||
|  |       "@typescript-eslint/no-inferrable-types": "error", | ||||||
|  |       "@typescript-eslint/no-misused-new": "error", | ||||||
|  |       "@typescript-eslint/no-namespace": "error", | ||||||
|  |       "@typescript-eslint/no-non-null-assertion": "warn", | ||||||
|  |       "@typescript-eslint/no-unnecessary-qualifier": "error", | ||||||
|  |       "@typescript-eslint/no-unnecessary-type-assertion": "error", | ||||||
|  |       "@typescript-eslint/no-useless-constructor": "error", | ||||||
|  |       "@typescript-eslint/no-var-requires": "error", | ||||||
|  |       "@typescript-eslint/prefer-for-of": "warn", | ||||||
|  |       "@typescript-eslint/prefer-function-type": "warn", | ||||||
|  |       "@typescript-eslint/prefer-includes": "error", | ||||||
|  |       "@typescript-eslint/prefer-string-starts-ends-with": "error", | ||||||
|  |       "@typescript-eslint/promise-function-async": "error", | ||||||
|  |       "@typescript-eslint/require-array-sort-compare": ["error", {"ignoreStringArrays":  true}], | ||||||
|  |       "@typescript-eslint/restrict-plus-operands": "error", | ||||||
|  |       "semi": "off", | ||||||
|  |       "@typescript-eslint/semi": ["error", "never"], | ||||||
|  |       "@typescript-eslint/type-annotation-spacing": "error", | ||||||
|  |       "@typescript-eslint/unbound-method": "error" | ||||||
|  |     }, | ||||||
|  |     "env": { | ||||||
|  |       "node": true, | ||||||
|  |       "es6": true, | ||||||
|  |       "jest/globals": true | ||||||
|  |     } | ||||||
|  |   } | ||||||
							
								
								
									
										16
									
								
								.github/actions/build-dist/action.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.github/actions/build-dist/action.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | name: 'Build and upload distribution' | ||||||
|  | # Builds the action distribution an uploads as an artifact for later download | ||||||
|  | runs: | ||||||
|  |   using: "composite" | ||||||
|  |   steps:  | ||||||
|  |     - name: Build distribution | ||||||
|  |       shell: bash | ||||||
|  |       run: | | ||||||
|  |         npm install | ||||||
|  |         npm run build | ||||||
|  |     - name: Upload distribution | ||||||
|  |       uses: actions/upload-artifact@v3 | ||||||
|  |       with: | ||||||
|  |         name: dist | ||||||
|  |         path: dist/ | ||||||
|  | 
 | ||||||
							
								
								
									
										12
									
								
								.github/actions/download-dist/action.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.github/actions/download-dist/action.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | name: 'Download dist' | ||||||
|  | # Downloads a 'dist' directory artifact that was uploaded in an earlier step | ||||||
|  | # We control this with an environment variable to allow for easier global configuration. | ||||||
|  | runs: | ||||||
|  |   using: "composite" | ||||||
|  |   steps:  | ||||||
|  |     - name: Download dist | ||||||
|  |       if: ${{ env.DOWNLOAD_DIST == 'true' }} | ||||||
|  |       uses: actions/download-artifact@v3 | ||||||
|  |       with: | ||||||
|  |         name: dist | ||||||
|  |         path: dist/ | ||||||
							
								
								
									
										51
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | version: 2 | ||||||
|  | registries: | ||||||
|  |   gradle-plugin-portal: | ||||||
|  |     type: maven-repository | ||||||
|  |     url: https://plugins.gradle.org/m2 | ||||||
|  |     username: dummy # Required by dependabot | ||||||
|  |     password: dummy # Required by dependabot | ||||||
|  | updates: | ||||||
|  |   - package-ecosystem: "npm" | ||||||
|  |     directory: "/" | ||||||
|  |     schedule: | ||||||
|  |       interval: "weekly" | ||||||
|  |     open-pull-requests-limit: 10 | ||||||
|  |     ignore: | ||||||
|  |       - dependency-name: "@types/node" | ||||||
|  |   - package-ecosystem: "gradle" | ||||||
|  |     directory: ".github/workflow-samples/gradle-plugin" | ||||||
|  |     registries: | ||||||
|  |       - gradle-plugin-portal | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |   - package-ecosystem: "gradle" | ||||||
|  |     directory: ".github/workflow-samples/groovy-dsl" | ||||||
|  |     registries: | ||||||
|  |       - gradle-plugin-portal | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |   - package-ecosystem: "gradle" | ||||||
|  |     directory: ".github/workflow-samples/java-toolchain" | ||||||
|  |     registries: | ||||||
|  |       - gradle-plugin-portal | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |   - package-ecosystem: "gradle" | ||||||
|  |     directory: ".github/workflow-samples/kotlin-dsl" | ||||||
|  |     registries: | ||||||
|  |       - gradle-plugin-portal | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |   - package-ecosystem: "gradle" | ||||||
|  |     directory: ".github/workflow-samples/no-wrapper" | ||||||
|  |     registries: | ||||||
|  |       - gradle-plugin-portal | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |   - package-ecosystem: "gradle" | ||||||
|  |     directory: ".github/workflow-samples/no-wrapper-gradle-5" | ||||||
|  |     registries: | ||||||
|  |       - gradle-plugin-portal | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
										
											Binary file not shown.
										
									
								
							| @ -1,8 +1,6 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d | distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip | ||||||
| networkTimeout=10000 |  | ||||||
| validateDistributionUrl=true |  | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								.github/workflow-samples/gradle-plugin/gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflow-samples/gradle-plugin/gradlew
									
									
									
									
										vendored
									
									
								
							| @ -55,7 +55,7 @@ | |||||||
| #       Darwin, MinGW, and NonStop. | #       Darwin, MinGW, and NonStop. | ||||||
| # | # | ||||||
| #   (3) This script is generated from the Groovy template | #   (3) This script is generated from the Groovy template | ||||||
| #       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | #       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||||
| #       within the Gradle project. | #       within the Gradle project. | ||||||
| # | # | ||||||
| #       You can find Gradle at https://github.com/gradle/gradle/. | #       You can find Gradle at https://github.com/gradle/gradle/. | ||||||
| @ -80,11 +80,13 @@ do | |||||||
|     esac |     esac | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| # This is normally unused | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | ||||||
| # shellcheck disable=SC2034 | 
 | ||||||
|  | APP_NAME="Gradle" | ||||||
| APP_BASE_NAME=${0##*/} | APP_BASE_NAME=${0##*/} | ||||||
| # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | 
 | ||||||
| APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
| 
 | 
 | ||||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
| MAX_FD=maximum | MAX_FD=maximum | ||||||
| @ -131,29 +133,22 @@ location of your Java installation." | |||||||
|     fi |     fi | ||||||
| else | else | ||||||
|     JAVACMD=java |     JAVACMD=java | ||||||
|     if ! command -v java >/dev/null 2>&1 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|     then |  | ||||||
|         die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |  | ||||||
| 
 | 
 | ||||||
| Please set the JAVA_HOME variable in your environment to match the | Please set the JAVA_HOME variable in your environment to match the | ||||||
| location of your Java installation." | location of your Java installation." | ||||||
|     fi |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # Increase the maximum file descriptors if we can. | # Increase the maximum file descriptors if we can. | ||||||
| if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||||
|     case $MAX_FD in #( |     case $MAX_FD in #( | ||||||
|       max*) |       max*) | ||||||
|         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         MAX_FD=$( ulimit -H -n ) || |         MAX_FD=$( ulimit -H -n ) || | ||||||
|             warn "Could not query maximum file descriptor limit" |             warn "Could not query maximum file descriptor limit" | ||||||
|     esac |     esac | ||||||
|     case $MAX_FD in  #( |     case $MAX_FD in  #( | ||||||
|       '' | soft) :;; #( |       '' | soft) :;; #( | ||||||
|       *) |       *) | ||||||
|         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         ulimit -n "$MAX_FD" || |         ulimit -n "$MAX_FD" || | ||||||
|             warn "Could not set maximum file descriptor limit to $MAX_FD" |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
|     esac |     esac | ||||||
| @ -198,15 +193,11 @@ if "$cygwin" || "$msys" ; then | |||||||
|     done |     done | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| 
 | # Collect all arguments for the java command; | ||||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | ||||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | #     shell script including quotes and variable substitutions, so put them in | ||||||
| 
 | #     double quotes to make sure that they get re-expanded; and | ||||||
| # Collect all arguments for the java command: | #   * put everything else in single quotes, so that it's not re-expanded. | ||||||
| #   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, |  | ||||||
| #     and any embedded shellness will be escaped. |  | ||||||
| #   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be |  | ||||||
| #     treated as '${Hostname}' itself on the command line. |  | ||||||
| 
 | 
 | ||||||
| set -- \ | set -- \ | ||||||
|         "-Dorg.gradle.appname=$APP_BASE_NAME" \ |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|  | |||||||
| @ -26,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal | |||||||
| 
 | 
 | ||||||
| set DIRNAME=%~dp0 | set DIRNAME=%~dp0 | ||||||
| if "%DIRNAME%"=="" set DIRNAME=. | if "%DIRNAME%"=="" set DIRNAME=. | ||||||
| @rem This is normally unused |  | ||||||
| set APP_BASE_NAME=%~n0 | set APP_BASE_NAME=%~n0 | ||||||
| set APP_HOME=%DIRNAME% | set APP_HOME=%DIRNAME% | ||||||
| 
 | 
 | ||||||
| @ -43,11 +42,11 @@ set JAVA_EXE=java.exe | |||||||
| %JAVA_EXE% -version >NUL 2>&1 | %JAVA_EXE% -version >NUL 2>&1 | ||||||
| if %ERRORLEVEL% equ 0 goto execute | if %ERRORLEVEL% equ 0 goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
| @ -57,11 +56,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |||||||
| 
 | 
 | ||||||
| if exist "%JAVA_EXE%" goto execute | if exist "%JAVA_EXE%" goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ testing { | |||||||
|         functionalTest(JvmTestSuite) { |         functionalTest(JvmTestSuite) { | ||||||
|             dependencies { |             dependencies { | ||||||
|                 // functionalTest test suite depends on the production code in tests |                 // functionalTest test suite depends on the production code in tests | ||||||
|                 implementation(project(':plugin')) |                 implementation project | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             targets { |             targets { | ||||||
|  | |||||||
| @ -11,8 +11,8 @@ dependencies { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tasks.named("test").configure { | tasks.named("test").configure { | ||||||
|     // Write marker file so we can detect if task was configured |     // Echo an output value so we can detect configuration-cache usage | ||||||
|     file("task-configured.txt").text = "true" |     println "::set-output name=task_configured::yes" | ||||||
| 
 | 
 | ||||||
|     doLast { |     doLast { | ||||||
|         if (System.properties.verifyCachedBuild) { |         if (System.properties.verifyCachedBuild) { | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| @ -1,8 +1,6 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d | distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip | ||||||
| networkTimeout=10000 |  | ||||||
| validateDistributionUrl=true |  | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								.github/workflow-samples/groovy-dsl/gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflow-samples/groovy-dsl/gradlew
									
									
									
									
										vendored
									
									
								
							| @ -55,7 +55,7 @@ | |||||||
| #       Darwin, MinGW, and NonStop. | #       Darwin, MinGW, and NonStop. | ||||||
| # | # | ||||||
| #   (3) This script is generated from the Groovy template | #   (3) This script is generated from the Groovy template | ||||||
| #       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | #       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||||
| #       within the Gradle project. | #       within the Gradle project. | ||||||
| # | # | ||||||
| #       You can find Gradle at https://github.com/gradle/gradle/. | #       You can find Gradle at https://github.com/gradle/gradle/. | ||||||
| @ -80,11 +80,13 @@ do | |||||||
|     esac |     esac | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| # This is normally unused | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | ||||||
| # shellcheck disable=SC2034 | 
 | ||||||
|  | APP_NAME="Gradle" | ||||||
| APP_BASE_NAME=${0##*/} | APP_BASE_NAME=${0##*/} | ||||||
| # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | 
 | ||||||
| APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
| 
 | 
 | ||||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
| MAX_FD=maximum | MAX_FD=maximum | ||||||
| @ -131,29 +133,22 @@ location of your Java installation." | |||||||
|     fi |     fi | ||||||
| else | else | ||||||
|     JAVACMD=java |     JAVACMD=java | ||||||
|     if ! command -v java >/dev/null 2>&1 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|     then |  | ||||||
|         die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |  | ||||||
| 
 | 
 | ||||||
| Please set the JAVA_HOME variable in your environment to match the | Please set the JAVA_HOME variable in your environment to match the | ||||||
| location of your Java installation." | location of your Java installation." | ||||||
|     fi |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # Increase the maximum file descriptors if we can. | # Increase the maximum file descriptors if we can. | ||||||
| if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||||
|     case $MAX_FD in #( |     case $MAX_FD in #( | ||||||
|       max*) |       max*) | ||||||
|         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         MAX_FD=$( ulimit -H -n ) || |         MAX_FD=$( ulimit -H -n ) || | ||||||
|             warn "Could not query maximum file descriptor limit" |             warn "Could not query maximum file descriptor limit" | ||||||
|     esac |     esac | ||||||
|     case $MAX_FD in  #( |     case $MAX_FD in  #( | ||||||
|       '' | soft) :;; #( |       '' | soft) :;; #( | ||||||
|       *) |       *) | ||||||
|         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         ulimit -n "$MAX_FD" || |         ulimit -n "$MAX_FD" || | ||||||
|             warn "Could not set maximum file descriptor limit to $MAX_FD" |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
|     esac |     esac | ||||||
| @ -198,15 +193,11 @@ if "$cygwin" || "$msys" ; then | |||||||
|     done |     done | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| 
 | # Collect all arguments for the java command; | ||||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | ||||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | #     shell script including quotes and variable substitutions, so put them in | ||||||
| 
 | #     double quotes to make sure that they get re-expanded; and | ||||||
| # Collect all arguments for the java command: | #   * put everything else in single quotes, so that it's not re-expanded. | ||||||
| #   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, |  | ||||||
| #     and any embedded shellness will be escaped. |  | ||||||
| #   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be |  | ||||||
| #     treated as '${Hostname}' itself on the command line. |  | ||||||
| 
 | 
 | ||||||
| set -- \ | set -- \ | ||||||
|         "-Dorg.gradle.appname=$APP_BASE_NAME" \ |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								.github/workflow-samples/groovy-dsl/gradlew.bat
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.github/workflow-samples/groovy-dsl/gradlew.bat
									
									
									
									
										vendored
									
									
								
							| @ -26,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal | |||||||
| 
 | 
 | ||||||
| set DIRNAME=%~dp0 | set DIRNAME=%~dp0 | ||||||
| if "%DIRNAME%"=="" set DIRNAME=. | if "%DIRNAME%"=="" set DIRNAME=. | ||||||
| @rem This is normally unused |  | ||||||
| set APP_BASE_NAME=%~n0 | set APP_BASE_NAME=%~n0 | ||||||
| set APP_HOME=%DIRNAME% | set APP_HOME=%DIRNAME% | ||||||
| 
 | 
 | ||||||
| @ -43,11 +42,11 @@ set JAVA_EXE=java.exe | |||||||
| %JAVA_EXE% -version >NUL 2>&1 | %JAVA_EXE% -version >NUL 2>&1 | ||||||
| if %ERRORLEVEL% equ 0 goto execute | if %ERRORLEVEL% equ 0 goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
| @ -57,11 +56,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |||||||
| 
 | 
 | ||||||
| if exist "%JAVA_EXE%" goto execute | if exist "%JAVA_EXE%" goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| plugins { | plugins { | ||||||
|     id "com.gradle.enterprise" version "3.16.2" |     id "com.gradle.enterprise" version "3.11.1" | ||||||
|     id "com.gradle.common-custom-user-data-gradle-plugin" version "1.13" |     id "com.gradle.common-custom-user-data-gradle-plugin" version "1.8" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gradleEnterprise { | gradleEnterprise { | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| @ -1,8 +1,6 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d | distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip | ||||||
| networkTimeout=10000 |  | ||||||
| validateDistributionUrl=true |  | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								.github/workflow-samples/java-toolchain/gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflow-samples/java-toolchain/gradlew
									
									
									
									
										vendored
									
									
								
							| @ -55,7 +55,7 @@ | |||||||
| #       Darwin, MinGW, and NonStop. | #       Darwin, MinGW, and NonStop. | ||||||
| # | # | ||||||
| #   (3) This script is generated from the Groovy template | #   (3) This script is generated from the Groovy template | ||||||
| #       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | #       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||||
| #       within the Gradle project. | #       within the Gradle project. | ||||||
| # | # | ||||||
| #       You can find Gradle at https://github.com/gradle/gradle/. | #       You can find Gradle at https://github.com/gradle/gradle/. | ||||||
| @ -80,11 +80,13 @@ do | |||||||
|     esac |     esac | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| # This is normally unused | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | ||||||
| # shellcheck disable=SC2034 | 
 | ||||||
|  | APP_NAME="Gradle" | ||||||
| APP_BASE_NAME=${0##*/} | APP_BASE_NAME=${0##*/} | ||||||
| # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | 
 | ||||||
| APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
| 
 | 
 | ||||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
| MAX_FD=maximum | MAX_FD=maximum | ||||||
| @ -131,29 +133,22 @@ location of your Java installation." | |||||||
|     fi |     fi | ||||||
| else | else | ||||||
|     JAVACMD=java |     JAVACMD=java | ||||||
|     if ! command -v java >/dev/null 2>&1 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|     then |  | ||||||
|         die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |  | ||||||
| 
 | 
 | ||||||
| Please set the JAVA_HOME variable in your environment to match the | Please set the JAVA_HOME variable in your environment to match the | ||||||
| location of your Java installation." | location of your Java installation." | ||||||
|     fi |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # Increase the maximum file descriptors if we can. | # Increase the maximum file descriptors if we can. | ||||||
| if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||||
|     case $MAX_FD in #( |     case $MAX_FD in #( | ||||||
|       max*) |       max*) | ||||||
|         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         MAX_FD=$( ulimit -H -n ) || |         MAX_FD=$( ulimit -H -n ) || | ||||||
|             warn "Could not query maximum file descriptor limit" |             warn "Could not query maximum file descriptor limit" | ||||||
|     esac |     esac | ||||||
|     case $MAX_FD in  #( |     case $MAX_FD in  #( | ||||||
|       '' | soft) :;; #( |       '' | soft) :;; #( | ||||||
|       *) |       *) | ||||||
|         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         ulimit -n "$MAX_FD" || |         ulimit -n "$MAX_FD" || | ||||||
|             warn "Could not set maximum file descriptor limit to $MAX_FD" |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
|     esac |     esac | ||||||
| @ -198,15 +193,11 @@ if "$cygwin" || "$msys" ; then | |||||||
|     done |     done | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| 
 | # Collect all arguments for the java command; | ||||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | ||||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | #     shell script including quotes and variable substitutions, so put them in | ||||||
| 
 | #     double quotes to make sure that they get re-expanded; and | ||||||
| # Collect all arguments for the java command: | #   * put everything else in single quotes, so that it's not re-expanded. | ||||||
| #   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, |  | ||||||
| #     and any embedded shellness will be escaped. |  | ||||||
| #   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be |  | ||||||
| #     treated as '${Hostname}' itself on the command line. |  | ||||||
| 
 | 
 | ||||||
| set -- \ | set -- \ | ||||||
|         "-Dorg.gradle.appname=$APP_BASE_NAME" \ |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|  | |||||||
| @ -26,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal | |||||||
| 
 | 
 | ||||||
| set DIRNAME=%~dp0 | set DIRNAME=%~dp0 | ||||||
| if "%DIRNAME%"=="" set DIRNAME=. | if "%DIRNAME%"=="" set DIRNAME=. | ||||||
| @rem This is normally unused |  | ||||||
| set APP_BASE_NAME=%~n0 | set APP_BASE_NAME=%~n0 | ||||||
| set APP_HOME=%DIRNAME% | set APP_HOME=%DIRNAME% | ||||||
| 
 | 
 | ||||||
| @ -43,11 +42,11 @@ set JAVA_EXE=java.exe | |||||||
| %JAVA_EXE% -version >NUL 2>&1 | %JAVA_EXE% -version >NUL 2>&1 | ||||||
| if %ERRORLEVEL% equ 0 goto execute | if %ERRORLEVEL% equ 0 goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
| @ -57,11 +56,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |||||||
| 
 | 
 | ||||||
| if exist "%JAVA_EXE%" goto execute | if exist "%JAVA_EXE%" goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1 @@ | |||||||
| plugins { |  | ||||||
|     id("org.gradle.toolchains.foojay-resolver-convention") version("0.7.0") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| rootProject.name = 'basic' | rootProject.name = 'basic' | ||||||
|  | |||||||
| @ -8,9 +8,9 @@ repositories { | |||||||
| 
 | 
 | ||||||
| dependencies { | dependencies { | ||||||
|     api("org.apache.commons:commons-math3:3.6.1") |     api("org.apache.commons:commons-math3:3.6.1") | ||||||
|     implementation("com.google.guava:guava:33.1.0-jre") |     implementation("com.google.guava:guava:31.1-jre") | ||||||
| 
 | 
 | ||||||
|     testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") |     testImplementation("org.junit.jupiter:junit-jupiter:5.9.0") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tasks.test { | tasks.test { | ||||||
| @ -18,8 +18,8 @@ tasks.test { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tasks.named("test").configure { | tasks.named("test").configure { | ||||||
|     // Write marker file so we can detect if task was configured |     // Echo an output value so we can detect configuration-cache usage | ||||||
|     file("task-configured.txt").writeText("true") |     println("::set-output name=task_configured::yes") | ||||||
| 
 | 
 | ||||||
|     doLast { |     doLast { | ||||||
|         if (System.getProperties().containsKey("verifyCachedBuild")) { |         if (System.getProperties().containsKey("verifyCachedBuild")) { | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| @ -1,8 +1,6 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d | distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip | ||||||
| networkTimeout=10000 |  | ||||||
| validateDistributionUrl=true |  | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								.github/workflow-samples/kotlin-dsl/gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflow-samples/kotlin-dsl/gradlew
									
									
									
									
										vendored
									
									
								
							| @ -55,7 +55,7 @@ | |||||||
| #       Darwin, MinGW, and NonStop. | #       Darwin, MinGW, and NonStop. | ||||||
| # | # | ||||||
| #   (3) This script is generated from the Groovy template | #   (3) This script is generated from the Groovy template | ||||||
| #       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | #       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||||
| #       within the Gradle project. | #       within the Gradle project. | ||||||
| # | # | ||||||
| #       You can find Gradle at https://github.com/gradle/gradle/. | #       You can find Gradle at https://github.com/gradle/gradle/. | ||||||
| @ -80,11 +80,13 @@ do | |||||||
|     esac |     esac | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| # This is normally unused | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | ||||||
| # shellcheck disable=SC2034 | 
 | ||||||
|  | APP_NAME="Gradle" | ||||||
| APP_BASE_NAME=${0##*/} | APP_BASE_NAME=${0##*/} | ||||||
| # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | 
 | ||||||
| APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
| 
 | 
 | ||||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
| MAX_FD=maximum | MAX_FD=maximum | ||||||
| @ -131,29 +133,22 @@ location of your Java installation." | |||||||
|     fi |     fi | ||||||
| else | else | ||||||
|     JAVACMD=java |     JAVACMD=java | ||||||
|     if ! command -v java >/dev/null 2>&1 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|     then |  | ||||||
|         die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |  | ||||||
| 
 | 
 | ||||||
| Please set the JAVA_HOME variable in your environment to match the | Please set the JAVA_HOME variable in your environment to match the | ||||||
| location of your Java installation." | location of your Java installation." | ||||||
|     fi |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # Increase the maximum file descriptors if we can. | # Increase the maximum file descriptors if we can. | ||||||
| if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||||
|     case $MAX_FD in #( |     case $MAX_FD in #( | ||||||
|       max*) |       max*) | ||||||
|         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         MAX_FD=$( ulimit -H -n ) || |         MAX_FD=$( ulimit -H -n ) || | ||||||
|             warn "Could not query maximum file descriptor limit" |             warn "Could not query maximum file descriptor limit" | ||||||
|     esac |     esac | ||||||
|     case $MAX_FD in  #( |     case $MAX_FD in  #( | ||||||
|       '' | soft) :;; #( |       '' | soft) :;; #( | ||||||
|       *) |       *) | ||||||
|         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. |  | ||||||
|         # shellcheck disable=SC2039,SC3045 |  | ||||||
|         ulimit -n "$MAX_FD" || |         ulimit -n "$MAX_FD" || | ||||||
|             warn "Could not set maximum file descriptor limit to $MAX_FD" |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
|     esac |     esac | ||||||
| @ -198,15 +193,11 @@ if "$cygwin" || "$msys" ; then | |||||||
|     done |     done | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| 
 | # Collect all arguments for the java command; | ||||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | ||||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | #     shell script including quotes and variable substitutions, so put them in | ||||||
| 
 | #     double quotes to make sure that they get re-expanded; and | ||||||
| # Collect all arguments for the java command: | #   * put everything else in single quotes, so that it's not re-expanded. | ||||||
| #   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, |  | ||||||
| #     and any embedded shellness will be escaped. |  | ||||||
| #   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be |  | ||||||
| #     treated as '${Hostname}' itself on the command line. |  | ||||||
| 
 | 
 | ||||||
| set -- \ | set -- \ | ||||||
|         "-Dorg.gradle.appname=$APP_BASE_NAME" \ |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								.github/workflow-samples/kotlin-dsl/gradlew.bat
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.github/workflow-samples/kotlin-dsl/gradlew.bat
									
									
									
									
										vendored
									
									
								
							| @ -26,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal | |||||||
| 
 | 
 | ||||||
| set DIRNAME=%~dp0 | set DIRNAME=%~dp0 | ||||||
| if "%DIRNAME%"=="" set DIRNAME=. | if "%DIRNAME%"=="" set DIRNAME=. | ||||||
| @rem This is normally unused |  | ||||||
| set APP_BASE_NAME=%~n0 | set APP_BASE_NAME=%~n0 | ||||||
| set APP_HOME=%DIRNAME% | set APP_HOME=%DIRNAME% | ||||||
| 
 | 
 | ||||||
| @ -43,11 +42,11 @@ set JAVA_EXE=java.exe | |||||||
| %JAVA_EXE% -version >NUL 2>&1 | %JAVA_EXE% -version >NUL 2>&1 | ||||||
| if %ERRORLEVEL% equ 0 goto execute | if %ERRORLEVEL% equ 0 goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
| @ -57,11 +56,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |||||||
| 
 | 
 | ||||||
| if exist "%JAVA_EXE%" goto execute | if exist "%JAVA_EXE%" goto execute | ||||||
| 
 | 
 | ||||||
| echo. 1>&2 | echo. | ||||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
| echo. 1>&2 | echo. | ||||||
| echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
| echo location of your Java installation. 1>&2 | echo location of your Java installation. | ||||||
| 
 | 
 | ||||||
| goto fail | goto fail | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| plugins { | plugins { | ||||||
|     id("com.gradle.enterprise") version "3.16.2" |     id("com.gradle.enterprise") version "3.11.1" | ||||||
|     id("com.gradle.common-custom-user-data-gradle-plugin") version "1.13" |     id("com.gradle.common-custom-user-data-gradle-plugin") version "1.8" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gradleEnterprise { | gradleEnterprise { | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								.github/workflow-samples/no-ge/build.gradle
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflow-samples/no-ge/build.gradle
									
									
									
									
										vendored
									
									
								
							| @ -1 +0,0 @@ | |||||||
| // Required to keep dependabot happy |  | ||||||
| @ -1 +0,0 @@ | |||||||
| rootProject.name = 'no-ge' |  | ||||||
| @ -1,5 +1,5 @@ | |||||||
| plugins { | plugins { | ||||||
|     id "com.gradle.build-scan" version "3.16.2" |     id "com.gradle.build-scan" version "3.11.1"  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gradleEnterprise { | gradleEnterprise { | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| plugins { | plugins { | ||||||
|     id "com.gradle.enterprise" version "3.16.2" |     id "com.gradle.enterprise" version "3.11.1" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gradleEnterprise { | gradleEnterprise { | ||||||
|  | |||||||
							
								
								
									
										70
									
								
								.github/workflows/ci-codeql.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								.github/workflows/ci-codeql.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | # For most projects, this workflow file will not need changing; you simply need | ||||||
|  | # to commit it to your repository. | ||||||
|  | # | ||||||
|  | # You may wish to alter this file to override the set of languages analyzed, | ||||||
|  | # or to provide custom queries or build logic. | ||||||
|  | # | ||||||
|  | # ******** NOTE ******** | ||||||
|  | # We have attempted to detect the languages in your repository. Please check | ||||||
|  | # the `language` matrix defined below to confirm you have the correct set of | ||||||
|  | # supported CodeQL languages. | ||||||
|  | # | ||||||
|  | name: CI-codeql | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: [ main ] | ||||||
|  |   pull_request: | ||||||
|  |     # The branches below must be a subset of the branches above | ||||||
|  |     branches: [ main ] | ||||||
|  |   schedule: | ||||||
|  |     - cron: '25 23 * * 2' | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   analyze: | ||||||
|  |     name: Analyze | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     permissions: | ||||||
|  |       actions: read | ||||||
|  |       contents: read | ||||||
|  |       security-events: write | ||||||
|  | 
 | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         language: [ 'javascript' ] | ||||||
|  |         # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] | ||||||
|  |         # Learn more about CodeQL language support at https://git.io/codeql-language-support | ||||||
|  | 
 | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout repository | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  | 
 | ||||||
|  |     # Initializes the CodeQL tools for scanning. | ||||||
|  |     - name: Initialize CodeQL | ||||||
|  |       uses: github/codeql-action/init@v2 | ||||||
|  |       with: | ||||||
|  |         languages: ${{ matrix.language }} | ||||||
|  |         # If you wish to specify custom queries, you can do so here or in a config file. | ||||||
|  |         # By default, queries listed here will override any specified in a config file. | ||||||
|  |         # Prefix the list here with "+" to use these queries and those in the config file. | ||||||
|  |         # queries: ./path/to/local/query, your-org/your-repo/queries@main | ||||||
|  | 
 | ||||||
|  |     # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java). | ||||||
|  |     # If this step fails, then you should remove it and run the build manually (see below) | ||||||
|  |     - name: Autobuild | ||||||
|  |       uses: github/codeql-action/autobuild@v2 | ||||||
|  | 
 | ||||||
|  |     # ℹ️ Command-line programs to run using the OS shell. | ||||||
|  |     # 📚 https://git.io/JvXDl | ||||||
|  | 
 | ||||||
|  |     # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines | ||||||
|  |     #    and modify them (or add more) to build your code if your project | ||||||
|  |     #    uses a compiled language | ||||||
|  | 
 | ||||||
|  |     #- run: | | ||||||
|  |     #   make bootstrap | ||||||
|  |     #   make release | ||||||
|  | 
 | ||||||
|  |     - name: Perform CodeQL Analysis | ||||||
|  |       uses: github/codeql-action/analyze@v2 | ||||||
							
								
								
									
										44
									
								
								.github/workflows/ci-full-check.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								.github/workflows/ci-full-check.yml
									
									
									
									
										vendored
									
									
								
							| @ -2,6 +2,16 @@ name: CI-full-check | |||||||
| 
 | 
 | ||||||
| on: | on: | ||||||
|   workflow_dispatch: |   workflow_dispatch: | ||||||
|  |   pull_request: | ||||||
|  |     types: | ||||||
|  |       - assigned | ||||||
|  |       - review_requested | ||||||
|  |   push: | ||||||
|  |     branches:  | ||||||
|  |       - main | ||||||
|  |     paths: | ||||||
|  |       - '.github/**' | ||||||
|  |       - 'dist/**' | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   action-inputs: |   action-inputs: | ||||||
| @ -9,20 +19,14 @@ jobs: | |||||||
|     with: |     with: | ||||||
|       cache-key-prefix: ${{github.run_number}}- |       cache-key-prefix: ${{github.run_number}}- | ||||||
| 
 | 
 | ||||||
|  |   cache-cleanup: | ||||||
|  |     needs: build-distribution | ||||||
|  |     uses: ./.github/workflows/integ-test-cache-cleanup.yml | ||||||
|  |     with: | ||||||
|  |       cache-key-prefix: ${{github.run_number}}- | ||||||
|  | 
 | ||||||
|   caching-config: |   caching-config: | ||||||
|     uses: ./.github/workflows/integ-test-caching-config.yml |     uses: ./.github/workflows/integ-test-action-inputs-caching.yml | ||||||
|     with: |  | ||||||
|       cache-key-prefix: ${{github.run_number}}- |  | ||||||
| 
 |  | ||||||
|   dependency-graph: |  | ||||||
|     uses: ./.github/workflows/integ-test-dependency-graph.yml |  | ||||||
|     permissions: |  | ||||||
|       contents: write |  | ||||||
|     with: |  | ||||||
|       cache-key-prefix: ${{github.run_number}}- |  | ||||||
| 
 |  | ||||||
|   dependency-graph-failures: |  | ||||||
|     uses: ./.github/workflows/integ-test-dependency-graph-failures.yml |  | ||||||
|     with: |     with: | ||||||
|       cache-key-prefix: ${{github.run_number}}- |       cache-key-prefix: ${{github.run_number}}- | ||||||
| 
 | 
 | ||||||
| @ -36,13 +40,6 @@ jobs: | |||||||
|     with: |     with: | ||||||
|       cache-key-prefix: ${{github.run_number}}- |       cache-key-prefix: ${{github.run_number}}- | ||||||
| 
 | 
 | ||||||
|   develocity-injection: |  | ||||||
|     uses: ./.github/workflows/integ-test-inject-develocity.yml |  | ||||||
|     with: |  | ||||||
|       cache-key-prefix: ${{github.run_number}}- |  | ||||||
|     secrets: |  | ||||||
|       DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }} |  | ||||||
| 
 |  | ||||||
|   provision-gradle-versions: |   provision-gradle-versions: | ||||||
|     uses: ./.github/workflows/integ-test-provision-gradle-versions.yml |     uses: ./.github/workflows/integ-test-provision-gradle-versions.yml | ||||||
|     with: |     with: | ||||||
| @ -52,8 +49,6 @@ jobs: | |||||||
|     uses: ./.github/workflows/integ-test-restore-configuration-cache.yml |     uses: ./.github/workflows/integ-test-restore-configuration-cache.yml | ||||||
|     with: |     with: | ||||||
|       cache-key-prefix: ${{github.run_number}}- |       cache-key-prefix: ${{github.run_number}}- | ||||||
|     secrets: |  | ||||||
|       GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
| 
 | 
 | ||||||
|   restore-custom-gradle-home: |   restore-custom-gradle-home: | ||||||
|     uses: ./.github/workflows/integ-test-restore-custom-gradle-home.yml |     uses: ./.github/workflows/integ-test-restore-custom-gradle-home.yml | ||||||
| @ -84,8 +79,3 @@ jobs: | |||||||
|     uses: ./.github/workflows/integ-test-sample-gradle-plugin.yml |     uses: ./.github/workflows/integ-test-sample-gradle-plugin.yml | ||||||
|     with: |     with: | ||||||
|       cache-key-prefix: ${{github.run_number}}- |       cache-key-prefix: ${{github.run_number}}- | ||||||
| 
 |  | ||||||
|   toolchain-detection: |  | ||||||
|     uses: ./.github/workflows/integ-test-detect-java-toolchains.yml |  | ||||||
|     with: |  | ||||||
|       cache-key-prefix: ${{github.run_number}}- |  | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								.github/workflows/ci-init-script-check.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.github/workflows/ci-init-script-check.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | name: CI-init-script-check | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     paths: | ||||||
|  |       - '.github/workflows/ci-init-script-check.yml' | ||||||
|  |       - 'src/resources/init-scripts/**' | ||||||
|  |       - 'test/init-scripts/**' | ||||||
|  |   workflow_dispatch: | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   test-init-scripts: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Setup Java | ||||||
|  |       uses: actions/setup-java@v3 | ||||||
|  |       with: | ||||||
|  |         distribution: temurin | ||||||
|  |         java-version: 8 | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: gradle/gradle-build-action@v2 # Use a released version to avoid breakages | ||||||
|  |     - name: Run integration tests | ||||||
|  |       working-directory: test/init-scripts | ||||||
|  |       run: ./gradlew check | ||||||
							
								
								
									
										81
									
								
								.github/workflows/ci-quick-check.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								.github/workflows/ci-quick-check.yml
									
									
									
									
										vendored
									
									
								
							| @ -3,86 +3,113 @@ name: CI-quick-check | |||||||
| on: | on: | ||||||
|   workflow_dispatch: |   workflow_dispatch: | ||||||
|   push: |   push: | ||||||
|  |     branches-ignore: main | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|  |   build-distribution: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Build and upload distribution | ||||||
|  |       uses: ./.github/actions/build-dist | ||||||
|  | 
 | ||||||
|  |   run-unit-tests: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Run tests | ||||||
|  |       run: | | ||||||
|  |         npm install | ||||||
|  |         npm run all | ||||||
|  | 
 | ||||||
|   action-inputs: |   action-inputs: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-action-inputs.yml |     uses: ./.github/workflows/integ-test-action-inputs.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
|  | 
 | ||||||
|  |   cache-cleanup: | ||||||
|  |     needs: build-distribution | ||||||
|  |     uses: ./.github/workflows/integ-test-cache-cleanup.yml | ||||||
|  |     with: | ||||||
|  |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
|  |       cache-key-prefix: ${{github.run_number}}- # Requires a fresh cache entry each run | ||||||
| 
 | 
 | ||||||
|   caching-config: |   caching-config: | ||||||
|     uses: ./.github/workflows/integ-test-caching-config.yml |     needs: build-distribution | ||||||
|     with: |     uses: ./.github/workflows/integ-test-action-inputs-caching.yml | ||||||
|       runner-os: '["ubuntu-latest"]' |  | ||||||
| 
 |  | ||||||
|   dependency-graph: |  | ||||||
|     uses: ./.github/workflows/integ-test-dependency-graph.yml |  | ||||||
|     permissions: |  | ||||||
|       contents: write |  | ||||||
|     with: |  | ||||||
|       runner-os: '["ubuntu-latest"]' |  | ||||||
| 
 |  | ||||||
|   dependency-graph-failures: |  | ||||||
|     uses: ./.github/workflows/integ-test-dependency-graph-failures.yml |  | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   execution-with-caching: |   execution-with-caching: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-execution-with-caching.yml |     uses: ./.github/workflows/integ-test-execution-with-caching.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   execution: |   execution: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-execution.yml |     uses: ./.github/workflows/integ-test-execution.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
| 
 |       download-dist: true | ||||||
|   develocity-injection: |  | ||||||
|     uses: ./.github/workflows/integ-test-inject-develocity.yml |  | ||||||
|     with: |  | ||||||
|       runner-os: '["ubuntu-latest"]' |  | ||||||
|     secrets: |  | ||||||
|       DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }} |  | ||||||
| 
 | 
 | ||||||
|   provision-gradle-versions: |   provision-gradle-versions: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-provision-gradle-versions.yml |     uses: ./.github/workflows/integ-test-provision-gradle-versions.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   restore-configuration-cache: |   restore-configuration-cache: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-restore-configuration-cache.yml |     uses: ./.github/workflows/integ-test-restore-configuration-cache.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|     secrets: |       download-dist: true | ||||||
|       GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
| 
 | 
 | ||||||
|   restore-containerized-gradle-home: |   restore-containerized-gradle-home: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-restore-containerized-gradle-home.yml |     uses: ./.github/workflows/integ-test-restore-containerized-gradle-home.yml | ||||||
|  |     with: | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   restore-custom-gradle-home: |   restore-custom-gradle-home: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-restore-custom-gradle-home.yml |     uses: ./.github/workflows/integ-test-restore-custom-gradle-home.yml | ||||||
|  |     with: | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   restore-gradle-home: |   restore-gradle-home: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-restore-gradle-home.yml |     uses: ./.github/workflows/integ-test-restore-gradle-home.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   restore-java-toolchain: |   restore-java-toolchain: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-restore-java-toolchain.yml |     uses: ./.github/workflows/integ-test-restore-java-toolchain.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   sample-kotlin-dsl: |   sample-kotlin-dsl: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-sample-kotlin-dsl.yml |     uses: ./.github/workflows/integ-test-sample-kotlin-dsl.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
|  |       download-dist: true | ||||||
| 
 | 
 | ||||||
|   sample-gradle-plugin: |   sample-gradle-plugin: | ||||||
|  |     needs: build-distribution | ||||||
|     uses: ./.github/workflows/integ-test-sample-gradle-plugin.yml |     uses: ./.github/workflows/integ-test-sample-gradle-plugin.yml | ||||||
|     with: |     with: | ||||||
|       runner-os: '["ubuntu-latest"]' |       runner-os: '["ubuntu-latest"]' | ||||||
| 
 |       download-dist: true | ||||||
|   toolchain-detection: |  | ||||||
|     uses: ./.github/workflows/integ-test-detect-java-toolchains.yml |  | ||||||
|     with: |  | ||||||
|       runner-os: '["ubuntu-latest"]' |  | ||||||
|  | |||||||
							
								
								
									
										38
									
								
								.github/workflows/ci-verify-outputs.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.github/workflows/ci-verify-outputs.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | name: CI-verify-outputs | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   pull_request: | ||||||
|  |     types: | ||||||
|  |       - assigned | ||||||
|  |       - review_requested | ||||||
|  |   push: | ||||||
|  |     branches:  | ||||||
|  |       - main | ||||||
|  |       - dependabot/** | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   check: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Build | ||||||
|  |       run: | | ||||||
|  |         npm install | ||||||
|  |         npm run all | ||||||
|  | 
 | ||||||
|  |     - name: Compare the expected and actual dist/ directories | ||||||
|  |       run: | | ||||||
|  |         if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then | ||||||
|  |           echo "Detected uncommitted changes after build.  See status below:" | ||||||
|  |           git diff | ||||||
|  |           exit 1 | ||||||
|  |         fi | ||||||
|  |       id: diff | ||||||
|  | 
 | ||||||
|  |     # If index.js was different than expected, upload the expected version as an artifact | ||||||
|  |     - uses: actions/upload-artifact@v3 | ||||||
|  |       if: ${{ failure() && steps.diff.conclusion == 'failure' }} | ||||||
|  |       with: | ||||||
|  |         name: dist | ||||||
|  |         path: dist/ | ||||||
							
								
								
									
										6
									
								
								.github/workflows/demo-failure-cases.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/demo-failure-cases.yml
									
									
									
									
										vendored
									
									
								
							| @ -9,7 +9,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Test build failure |     - name: Test build failure | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       continue-on-error: true |       continue-on-error: true | ||||||
| @ -21,7 +21,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Test wrapper missing |     - name: Test wrapper missing | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       continue-on-error: true |       continue-on-error: true | ||||||
| @ -33,7 +33,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Test bad config value |     - name: Test bad config value | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       continue-on-error: true |       continue-on-error: true | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								.github/workflows/demo-job-summary.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								.github/workflows/demo-job-summary.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| name: Demo Job Summary, for Gradle builds | name: Demo Job Summary for Gradle builds | ||||||
| 
 | 
 | ||||||
| on: | on: | ||||||
|   workflow_dispatch: |   workflow_dispatch: | ||||||
| @ -8,20 +8,25 @@ env: | |||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   many-gradle-builds: |   run-gradle-builds: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Build distribution | ||||||
|  |       shell: bash | ||||||
|  |       run: | | ||||||
|  |         npm install | ||||||
|  |         npm run build | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|     - name: Build kotlin-dsl project |     - name: Build kotlin-dsl project | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: ./gradlew assemble |       run: ./gradlew assemble | ||||||
|     - name: Build kotlin-dsl project without Build Scan® |     - name: Build kotlin-dsl project without build scan | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: ./gradlew assemble check --no-scan |       run: ./gradlew assemble check --no-scan | ||||||
|     - name: Build kotlin-dsl project with Build Scan® publish failure |     - name: Build kotlin-dsl project with build scan publish failure | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: ./gradlew check -Dgradle.enterprise.url=https://not.valid.server |       run: ./gradlew check -Dgradle.enterprise.url=https://not.valid.server | ||||||
|     - name: Build groovy-dsl project |     - name: Build groovy-dsl project | ||||||
| @ -36,36 +41,3 @@ jobs: | |||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
|       continue-on-error: true |       continue-on-error: true | ||||||
|       run: ./gradlew not-a-real-task |       run: ./gradlew not-a-real-task | ||||||
| 
 |  | ||||||
|   successful-builds-with-no-summary: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         add-job-summary: on-failure |  | ||||||
|     - name: Build kotlin-dsl project |  | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |  | ||||||
|       run: ./gradlew assemble |  | ||||||
|     - name: Build kotlin-dsl project without Build Scan® |  | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |  | ||||||
|       run: ./gradlew assemble check --no-scan |  | ||||||
| 
 |  | ||||||
|   pre-existing-gradle-home: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Pre-create Gradle User Home |  | ||||||
|       shell: bash |  | ||||||
|       run: | |  | ||||||
|         mkdir ~/.gradle |  | ||||||
|         mkdir ~/.gradle/caches |  | ||||||
|         touch ~/.gradle/caches/dummy.txt |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|     - name: Run build |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: ./gradlew assemble |  | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								.github/workflows/demo-pr-build-scan-comment.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								.github/workflows/demo-pr-build-scan-comment.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,51 +1,27 @@ | |||||||
| name: Demo adding Build Scan® comment to PR | name: Demo adding build scan comment to PR | ||||||
| on: | on: | ||||||
|   pull_request: |   pull_request: | ||||||
|     types: [assigned, review_requested] |     types: [assigned, review_requested] | ||||||
| 
 |  | ||||||
| permissions: |  | ||||||
|   pull-requests: write |  | ||||||
| 
 |  | ||||||
| jobs: | jobs: | ||||||
|   successful-build-with-always-comment: |   gradle: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout project sources |     - name: Checkout project sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |  | ||||||
|         add-job-summary-as-pr-comment: always |  | ||||||
|     - name: Run build with Gradle wrapper |     - name: Run build with Gradle wrapper | ||||||
|       id: gradle |       id: gradle | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: ./gradlew build --scan |       run: ./gradlew build --scan | ||||||
| 
 |     - name: "Add build scan URL as PR comment" | ||||||
|   successful-build-with-comment-on-failure: |       uses: actions/github-script@v6 | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout project sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|       with: |       with: | ||||||
|         add-job-summary-as-pr-comment: on-failure |         github-token: ${{secrets.GITHUB_TOKEN}} | ||||||
|     - name: Run build with Gradle wrapper |         script: | | ||||||
|       id: gradle |           github.rest.issues.createComment({ | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |             issue_number: context.issue.number, | ||||||
|       run: ./gradlew build --scan |             owner: context.repo.owner, | ||||||
| 
 |             repo: context.repo.repo, | ||||||
|   failing-build-with-comment-on-failure: |             body: 'PR ready for review: ${{ steps.gradle.outputs.build-scan-url }}' | ||||||
|     runs-on: ubuntu-latest |           }) | ||||||
|     steps: |  | ||||||
|     - name: Checkout project sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         add-job-summary-as-pr-comment: on-failure |  | ||||||
|     - name: Run build with Gradle wrapper |  | ||||||
|       id: gradle |  | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |  | ||||||
|       run: ./gradlew no-a-real-task --scan |  | ||||||
|       continue-on-error: true |  | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| name: Test caching configuration | name: Test action inputs for caching | ||||||
| 
 | 
 | ||||||
| on: | on: | ||||||
|   workflow_call: |   workflow_call: | ||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-caching-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-caching-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -32,8 +38,7 @@ jobs: | |||||||
|             enterprise |             enterprise | ||||||
|         # Exclude build-cache from main cache entry |         # Exclude build-cache from main cache entry | ||||||
|         gradle-home-cache-excludes: | |         gradle-home-cache-excludes: | | ||||||
|             caches/build-cache-* |             caches/build-cache-1 | ||||||
|             caches/*/executionHistory |  | ||||||
|     - name: Build using Gradle wrapper |     - name: Build using Gradle wrapper | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
|       run: ./gradlew test |       run: ./gradlew test | ||||||
| @ -47,7 +52,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -56,8 +63,7 @@ jobs: | |||||||
|             caches |             caches | ||||||
|             enterprise |             enterprise | ||||||
|         gradle-home-cache-excludes: | |         gradle-home-cache-excludes: | | ||||||
|             caches/build-cache-* |             caches/build-cache-1 | ||||||
|             caches/*/executionHistory |  | ||||||
|         cache-read-only: true |         cache-read-only: true | ||||||
|     - name: Execute Gradle build with --offline |     - name: Execute Gradle build with --offline | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
| @ -71,7 +77,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -80,19 +88,21 @@ jobs: | |||||||
|       id: gradle |       id: gradle | ||||||
|       working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} |       working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} | ||||||
|       run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}" |       run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}" | ||||||
|     - name: Check Build Scan url is captured |     - name: Check build scan url is captured | ||||||
|       if: ${{ !steps.gradle.outputs.build-scan-url }} |       if: ${{ !steps.gradle.outputs.build-scan-url }} | ||||||
|       uses: actions/github-script@v7 |       uses: actions/github-script@v6 | ||||||
|       with: |       with: | ||||||
|         script: | |         script: | | ||||||
|           core.setFailed('No Build Scan detected') |           core.setFailed('No build scan detected') | ||||||
| 
 | 
 | ||||||
|   # Test that build scans are captured when caching is disabled because Gradle User Home already exists |   # Test that build scans are captured when caching is disabled because Gradle User Home already exists | ||||||
|   cache-disabled-pre-existing-gradle-home: |   cache-disabled-pre-existing-gradle-home: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Create dummy Gradle User Home |     - name: Create dummy Gradle User Home | ||||||
|       run: mkdir -p ~/.gradle/caches |       run: mkdir -p ~/.gradle/caches | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
| @ -101,12 +111,12 @@ jobs: | |||||||
|       id: gradle |       id: gradle | ||||||
|       working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} |       working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} | ||||||
|       run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}" |       run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}" | ||||||
|     - name: Check Build Scan url is captured |     - name: Check build scan url is captured | ||||||
|       if: ${{ !steps.gradle.outputs.build-scan-url }} |       if: ${{ !steps.gradle.outputs.build-scan-url }} | ||||||
|       uses: actions/github-script@v7 |       uses: actions/github-script@v6 | ||||||
|       with: |       with: | ||||||
|         script: | |         script: | | ||||||
|           core.setFailed('No Build Scan detected') |           core.setFailed('No build scan detected') | ||||||
| 
 | 
 | ||||||
|   # Test seed the cache with cache-write-only and verify with cache-read-only |   # Test seed the cache with cache-write-only and verify with cache-read-only | ||||||
|   seed-build-write-only: |   seed-build-write-only: | ||||||
| @ -118,7 +128,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -137,7 +149,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Invoke with multi-line arguments |     - name: Invoke with multi-line arguments | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|  | |||||||
							
								
								
									
										86
									
								
								.github/workflows/integ-test-cache-cleanup.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								.github/workflows/integ-test-cache-cleanup.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | |||||||
|  | name: Test cache cleanup | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   workflow_call: | ||||||
|  |     inputs: | ||||||
|  |       cache-key-prefix: | ||||||
|  |         type: string | ||||||
|  |       runner-os: | ||||||
|  |         type: string | ||||||
|  |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
|  | 
 | ||||||
|  | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|  |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: integ-test-cache-cleanup-${{ inputs.cache-key-prefix }} | ||||||
|  |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   full-build: | ||||||
|  |     strategy: | ||||||
|  |       matrix: | ||||||
|  |         os: ${{fromJSON(inputs.runner-os)}} | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: ./ | ||||||
|  |       with: | ||||||
|  |         cache-read-only: false # For testing, allow writing cache entries on non-default branches | ||||||
|  |     - name: Build with 3.1 | ||||||
|  |       working-directory: test/jest/resources/cache-cleanup | ||||||
|  |       run: gradle --no-daemon --build-cache -Dcommons-math3.version=3.1 build | ||||||
|  | 
 | ||||||
|  |   # Second build will use the cache from the first build, but cleanup should remove unused artifacts | ||||||
|  |   assemble-build: | ||||||
|  |     needs: full-build | ||||||
|  |     strategy: | ||||||
|  |       matrix: | ||||||
|  |         os: ${{fromJSON(inputs.runner-os)}} | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: ./ | ||||||
|  |       with: | ||||||
|  |         cache-read-only: false | ||||||
|  |         gradle-home-cache-cleanup: true | ||||||
|  |     - name: Build with 3.1.1 | ||||||
|  |       working-directory: test/jest/resources/cache-cleanup | ||||||
|  |       run: gradle --no-daemon --build-cache -Dcommons-math3.version=3.1.1 build | ||||||
|  | 
 | ||||||
|  |   check-clean-cache: | ||||||
|  |     needs: assemble-build | ||||||
|  |     strategy: | ||||||
|  |       matrix: | ||||||
|  |         os: ${{fromJSON(inputs.runner-os)}} | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: ./ | ||||||
|  |       with: | ||||||
|  |         cache-read-only: true | ||||||
|  |     - name: Report Gradle User Home | ||||||
|  |       run: du -hc ~/.gradle/caches/modules-2 | ||||||
|  |     - name: Verify cleaned cache | ||||||
|  |       run: | | ||||||
|  |         if [ ! -e ~/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-math3/3.1.1 ]; then | ||||||
|  |           echo "::error ::Should find commons-math3 3.1.1 in cache" | ||||||
|  |           exit 1 | ||||||
|  |         fi | ||||||
|  |         if [ -e ~/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-math3/3.1 ]; then | ||||||
|  |           echo "::error ::Should NOT find commons-math3 3.1 in cache" | ||||||
|  |           exit 1 | ||||||
|  |         fi | ||||||
| @ -1,91 +0,0 @@ | |||||||
| name: Test dependency graph |  | ||||||
| 
 |  | ||||||
| on: |  | ||||||
|   workflow_call: |  | ||||||
|     inputs: |  | ||||||
|       cache-key-prefix: |  | ||||||
|         type: string |  | ||||||
|       runner-os: |  | ||||||
|         type: string |  | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |  | ||||||
| 
 |  | ||||||
| env: |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }} |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |  | ||||||
| 
 |  | ||||||
| jobs: |  | ||||||
|   unsupported-gradle-version-warning: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         gradle-version: 7.0.1 |  | ||||||
|         dependency-graph: generate |  | ||||||
|         dependency-graph-continue-on-failure: true |  | ||||||
|     - name: Run with unsupported Gradle version |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: | |  | ||||||
|         if gradle help | grep -q 'warning::Dependency Graph is not supported for Gradle 7.0.1. No dependency snapshot will be generated.'; |  | ||||||
|         then |  | ||||||
|           echo "Got the expected warning" |  | ||||||
|         else |  | ||||||
|           echo "Did not get the expected warning" |  | ||||||
|           exit 1 |  | ||||||
|         fi |  | ||||||
| 
 |  | ||||||
|   unsupported-gradle-version-failure: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         gradle-version: 7.0.1 |  | ||||||
|         dependency-graph: generate |  | ||||||
|         dependency-graph-continue-on-failure: false |  | ||||||
|     - name: Run with unsupported Gradle version |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: | |  | ||||||
|         if gradle help; then |  | ||||||
|           echo "Expected build to fail with Gradle 7.0.1" |  | ||||||
|           exit 1 |  | ||||||
|         fi |  | ||||||
| 
 |  | ||||||
|   insufficient-permissions-warning: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     permissions: |  | ||||||
|       contents: read |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: generate-and-submit |  | ||||||
|         dependency-graph-continue-on-failure: true |  | ||||||
|     - name: Run with insufficient permissions |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: ./gradlew help |  | ||||||
|       # This test is primarily for demonstration: it's unclear how to check for warnings emitted in the post-action |  | ||||||
| 
 |  | ||||||
|   SHOULD_FAIL-insufficient-permissions-failure: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     permissions: |  | ||||||
|       contents: read |  | ||||||
|     continue-on-error: true |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: generate-and-submit |  | ||||||
|         dependency-graph-continue-on-failure: false |  | ||||||
|     - name: Run with insufficient permissions |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: ./gradlew help |  | ||||||
|       # This test is primarily for demonstration: it's unclear how to check for a failure in the post-action |  | ||||||
							
								
								
									
										134
									
								
								.github/workflows/integ-test-dependency-graph.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										134
									
								
								.github/workflows/integ-test-dependency-graph.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,134 +0,0 @@ | |||||||
| name: Test dependency graph |  | ||||||
| 
 |  | ||||||
| on: |  | ||||||
|   workflow_call: |  | ||||||
|     inputs: |  | ||||||
|       cache-key-prefix: |  | ||||||
|         type: string |  | ||||||
|       runner-os: |  | ||||||
|         type: string |  | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |  | ||||||
| 
 |  | ||||||
| permissions: |  | ||||||
|   contents: write |  | ||||||
| 
 |  | ||||||
| env: |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }} |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |  | ||||||
| 
 |  | ||||||
| jobs: |  | ||||||
|   groovy-generate: |  | ||||||
|     strategy: |  | ||||||
|       matrix: |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ${{ matrix.os }} |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: generate-and-upload |  | ||||||
|     - name: Run gradle build |  | ||||||
|       run: ./gradlew build |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
| 
 |  | ||||||
|   kotlin-generate: |  | ||||||
|     strategy: |  | ||||||
|       matrix: |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ${{ matrix.os }} |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: generate-and-submit |  | ||||||
|     - name: Run gradle build |  | ||||||
|       run: ./gradlew build |  | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |  | ||||||
|    |  | ||||||
|   submit: |  | ||||||
|     needs: [groovy-generate] |  | ||||||
|     runs-on: "ubuntu-latest" |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Submit dependency graphs |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: download-and-submit |  | ||||||
| 
 |  | ||||||
|   multiple-builds: |  | ||||||
|     strategy: |  | ||||||
|       matrix: |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ${{ matrix.os }} |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: generate-and-submit |  | ||||||
|     - id: gradle-assemble |  | ||||||
|       run: ./gradlew assemble |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|     - id: gradle-build |  | ||||||
|       run: ./gradlew build |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|     - id: gradle-build-again |  | ||||||
|       run: ./gradlew build |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|     - name: Check generated dependency graphs |  | ||||||
|       shell: bash |  | ||||||
|       run: | |  | ||||||
|         echo "gradle-assemble report file: ${{ steps.gradle-assemble.outputs.dependency-graph-file }}" |  | ||||||
|         echo "gradle-build report file: ${{ steps.gradle-build.outputs.dependency-graph-file }}" |  | ||||||
|         echo "gradle-build-again report file: ${{ steps.gradle-build-again.outputs.dependency-graph-file }}" |  | ||||||
|         ls -l dependency-graph-reports |  | ||||||
|         if [ ! -e "${{ steps.gradle-assemble.outputs.dependency-graph-file }}" ]; then |  | ||||||
|             echo "Did not find gradle-assemble dependency graph file" |  | ||||||
|             exit 1 |  | ||||||
|         fi |  | ||||||
|         if [ ! -e "${{ steps.gradle-build.outputs.dependency-graph-file }}" ]; then |  | ||||||
|             echo "Did not find gradle-build dependency graph files" |  | ||||||
|             exit 1 |  | ||||||
|         fi |  | ||||||
|         if [ ! -e "${{ steps.gradle-build-again.outputs.dependency-graph-file }}" ]; then |  | ||||||
|             echo "Did not find gradle-build-again dependency graph files" |  | ||||||
|             exit 1 |  | ||||||
|         fi |  | ||||||
|          |  | ||||||
|   config-cache: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle for dependency-graph generate |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         dependency-graph: generate-and-submit |  | ||||||
|     - id: config-cache-store |  | ||||||
|       run: ./gradlew assemble --configuration-cache |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|     - name: Check and delete generated dependency graph |  | ||||||
|       shell: bash |  | ||||||
|       run: | |  | ||||||
|         if [ ! -e "${{ steps.config-cache-store.outputs.dependency-graph-file }}" ]; then |  | ||||||
|             echo "Did not find config-cache-store dependency graph files" |  | ||||||
|             exit 1 |  | ||||||
|         fi |  | ||||||
|         rm ${{ steps.config-cache-store.outputs.dependency-graph-file }} |  | ||||||
|     - id: config-cache-reuse |  | ||||||
|       run: ./gradlew assemble --configuration-cache |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|     - name: Check no dependency graph is generated |  | ||||||
|       shell: bash |  | ||||||
|       run: | |  | ||||||
|         if [ ! -z "$(ls -A dependency-graph-reports)" ]; then |  | ||||||
|             echo "Expected no dependency graph files to be generated" |  | ||||||
|             ls -l dependency-graph-reports |  | ||||||
|             exit 1 |  | ||||||
|         fi         |  | ||||||
| @ -1,85 +0,0 @@ | |||||||
| name: Test detect java toolchains |  | ||||||
| 
 |  | ||||||
| on: |  | ||||||
|   workflow_call: |  | ||||||
|     inputs: |  | ||||||
|       cache-key-prefix: |  | ||||||
|         type: string |  | ||||||
|       runner-os: |  | ||||||
|         type: string |  | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |  | ||||||
| 
 |  | ||||||
| env: |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: detect-java-toolchain-${{ inputs.cache-key-prefix }} |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |  | ||||||
| 
 |  | ||||||
| jobs: |  | ||||||
|   # Test that pre-installed runner JDKs are detected |  | ||||||
|   pre-installed-toolchains: |  | ||||||
|     strategy: |  | ||||||
|       fail-fast: false |  | ||||||
|       matrix: |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ${{ matrix.os }} |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|     - name: List detected toolchains |  | ||||||
|       shell: bash |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: |  |  | ||||||
|         gradle --info javaToolchains > output.txt |  | ||||||
|         cat output.txt |  | ||||||
|     - name: Verify detected toolchains |  | ||||||
|       shell: bash |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: |  |  | ||||||
|         grep -q 'Eclipse Temurin JDK 1.8' output.txt || (echo "::error::Did not detect preinstalled JDK 1.8" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 11' output.txt || (echo "::error::Did not detect preinstalled JDK 11" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 17' output.txt || (echo "::error::Did not detect preinstalled JDK 17" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 21' output.txt || (echo "::error::Did not detect preinstalled JDK 21" && exit 1) |  | ||||||
| 
 |  | ||||||
|   # Test that JDKs provisioned by setup-java are detected |  | ||||||
|   setup-java-installed-toolchain: |  | ||||||
|     strategy: |  | ||||||
|       fail-fast: false |  | ||||||
|       matrix: |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ${{ matrix.os }} |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Java 20 |  | ||||||
|       uses: actions/setup-java@v4 |  | ||||||
|       with: |  | ||||||
|         distribution: 'temurin' |  | ||||||
|         java-version: '20' |  | ||||||
|     - name: Setup Java 16 |  | ||||||
|       uses: actions/setup-java@v4 |  | ||||||
|       with: |  | ||||||
|         distribution: 'temurin' |  | ||||||
|         java-version: '16' |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|     - name: List detected toolchains |  | ||||||
|       shell: bash |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: |  |  | ||||||
|         gradle --info javaToolchains > output.txt |  | ||||||
|         cat output.txt |  | ||||||
|     - name: Verify setup JDKs are detected |  | ||||||
|       shell: bash |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: |  |  | ||||||
|         grep -q 'Eclipse Temurin JDK 16' output.txt || (echo "::error::Did not detect setup-java installed JDK 16" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 20' output.txt || (echo "::error::Did not detect setup-java installed JDK 20" && exit 1) |  | ||||||
|     - name: Verify pre-installed toolchains are detected |  | ||||||
|       shell: bash |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: |  |  | ||||||
|         grep -q 'Eclipse Temurin JDK 1.8' output.txt || (echo "::error::Did not detect preinstalled JDK 1.8" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 11' output.txt || (echo "::error::Did not detect preinstalled JDK 11" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 17' output.txt || (echo "::error::Did not detect preinstalled JDK 17" && exit 1) |  | ||||||
|         grep -q 'Eclipse Temurin JDK 21' output.txt || (echo "::error::Did not detect preinstalled JDK 21" && exit 1) |  | ||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: execution-with-caching-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: execution-with-caching-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Execute Gradle build |     - name: Execute Gradle build | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -38,7 +44,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Execute Gradle build |     - name: Execute Gradle build | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								.github/workflows/integ-test-execution.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								.github/workflows/integ-test-execution.yml
									
									
									
									
										vendored
									
									
								
							| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: execution-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: execution-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -26,7 +30,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Test use defined Gradle version |     - name: Test use defined Gradle version | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -40,6 +46,12 @@ jobs: | |||||||
|         gradle-version: release-candidate |         gradle-version: release-candidate | ||||||
|         build-root-directory: .github/workflow-samples/no-wrapper |         build-root-directory: .github/workflow-samples/no-wrapper | ||||||
|         arguments: help |         arguments: help | ||||||
|  |     - name: Test use defined Gradle executable | ||||||
|  |       uses: ./ | ||||||
|  |       with: | ||||||
|  |         gradle-executable: .github/workflow-samples/groovy-dsl/gradlew${{ matrix.script-suffix }} | ||||||
|  |         build-root-directory: .github/workflow-samples/no-wrapper | ||||||
|  |         arguments: help | ||||||
| 
 | 
 | ||||||
|   gradle-versions: |   gradle-versions: | ||||||
|     strategy: |     strategy: | ||||||
| @ -56,9 +68,11 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Java |     - name: Setup Java | ||||||
|       uses: actions/setup-java@v4 |       uses: actions/setup-java@v3 | ||||||
|       with: |       with: | ||||||
|         distribution: temurin |         distribution: temurin | ||||||
|         java-version: 8 |         java-version: 8 | ||||||
| @ -70,11 +84,11 @@ jobs: | |||||||
|         gradle-version: ${{matrix.gradle}} |         gradle-version: ${{matrix.gradle}} | ||||||
|         build-root-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} |         build-root-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} | ||||||
|         arguments: help -DgradleVersionCheck=${{matrix.gradle}} |         arguments: help -DgradleVersionCheck=${{matrix.gradle}} | ||||||
|     - name: Check Build Scan url |     - name: Check build scan url | ||||||
|       if: ${{ !steps.gradle.outputs.build-scan-url }} |       if: ${{ !steps.gradle.outputs.build-scan-url }} | ||||||
|       uses: actions/github-script@v7 |       uses: actions/github-script@v6 | ||||||
|       with: |       with: | ||||||
|         script: | |         script: | | ||||||
|           core.setFailed('No Build Scan detected')     |           core.setFailed('No build scan detected')     | ||||||
|    |    | ||||||
|     |     | ||||||
|  | |||||||
| @ -1,89 +0,0 @@ | |||||||
| name: Test develocity injection |  | ||||||
| 
 |  | ||||||
| on: |  | ||||||
|   workflow_call: |  | ||||||
|     inputs: |  | ||||||
|       cache-key-prefix: |  | ||||||
|         type: string |  | ||||||
|       runner-os: |  | ||||||
|         type: string |  | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |  | ||||||
|     secrets: |  | ||||||
|       DEVELOCITY_ACCESS_KEY: |  | ||||||
|         required: true |  | ||||||
| 
 |  | ||||||
| env: |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: provision-gradle-versions-${{ inputs.cache-key-prefix }} |  | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |  | ||||||
| 
 |  | ||||||
| jobs: |  | ||||||
|   inject-develocity: |  | ||||||
|     env: |  | ||||||
|       DEVELOCITY_INJECTION_ENABLED: true |  | ||||||
|       DEVELOCITY_URL: https://ge.solutions-team.gradle.com |  | ||||||
|       DEVELOCITY_PLUGIN_VERSION: 3.16.2 |  | ||||||
|       DEVELOCITY_CCUD_PLUGIN_VERSION: 1.13 |  | ||||||
|       GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # This env var has not (yet) been renamed/aliased in GE plugin 3.16.2 |  | ||||||
|     strategy: |  | ||||||
|       matrix: |  | ||||||
|         gradle: [current, 7.6.2, 6.9.4, 5.6.4] |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Java |  | ||||||
|       uses: actions/setup-java@v4 |  | ||||||
|       with: |  | ||||||
|         distribution: temurin |  | ||||||
|         java-version: 8 |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       id: setup-gradle |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         cache-read-only: false # For testing, allow writing cache entries on non-default branches |  | ||||||
|         gradle-version: ${{ matrix.gradle }} |  | ||||||
|     - name: Run Gradle build |  | ||||||
|       id: gradle |  | ||||||
|       working-directory: .github/workflow-samples/no-ge |  | ||||||
|       run: gradle help |  | ||||||
|     - name: Check Build Scan url |  | ||||||
|       if: ${{ !steps.gradle.outputs.build-scan-url }} |  | ||||||
|       uses: actions/github-script@v7 |  | ||||||
|       with: |  | ||||||
|         script: | |  | ||||||
|           core.setFailed('No Build Scan detected')    |  | ||||||
| 
 |  | ||||||
|   build-scan-publish: |  | ||||||
|     strategy: |  | ||||||
|       matrix: |  | ||||||
|         gradle: [current, 7.6.2, 6.9.4, 5.6.4] |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Setup Java |  | ||||||
|       uses: actions/setup-java@v4 |  | ||||||
|       with: |  | ||||||
|         distribution: temurin |  | ||||||
|         java-version: 8 |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       id: setup-gradle |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         cache-read-only: false # For testing, allow writing cache entries on non-default branches |  | ||||||
|         gradle-version: ${{ matrix.gradle }} |  | ||||||
|         build-scan-publish: true |  | ||||||
|         build-scan-terms-of-service-url: "https://gradle.com/terms-of-service" |  | ||||||
|         build-scan-terms-of-service-agree: "yes" |  | ||||||
|     - name: Run Gradle build |  | ||||||
|       id: gradle |  | ||||||
|       working-directory: .github/workflow-samples/no-ge |  | ||||||
|       run: gradle help |  | ||||||
|     - name: Check Build Scan url |  | ||||||
|       if: ${{ !steps.gradle.outputs.build-scan-url }} |  | ||||||
|       uses: actions/github-script@v7 |  | ||||||
|       with: |  | ||||||
|         script: | |  | ||||||
|           core.setFailed('No Build Scan detected')    |  | ||||||
| 
 |  | ||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: provision-gradle-versions-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: provision-gradle-versions-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -26,7 +30,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle with v6.9 |     - name: Setup Gradle with v6.9 | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -49,17 +55,6 @@ jobs: | |||||||
|     - name: Test use release-candidate |     - name: Test use release-candidate | ||||||
|       working-directory: .github/workflow-samples/no-wrapper |       working-directory: .github/workflow-samples/no-wrapper | ||||||
|       run: gradle help |       run: gradle help | ||||||
|     - name: Setup Gradle with current |  | ||||||
|       id: gradle-current |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         gradle-version: current |  | ||||||
|     - name: Check current version output parameter |  | ||||||
|       if: ${{ !startsWith(steps.gradle-current.outputs.gradle-version , '8.') }} |  | ||||||
|       uses: actions/github-script@v7 |  | ||||||
|       with: |  | ||||||
|         script: | |  | ||||||
|           core.setFailed('Gradle version parameter not set correctly: value was "${{ steps.gradle-current.outputs.gradle-version }}"')     |  | ||||||
|    |    | ||||||
|   gradle-versions: |   gradle-versions: | ||||||
|     strategy: |     strategy: | ||||||
| @ -76,33 +71,28 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Java |     - name: Setup Java | ||||||
|       uses: actions/setup-java@v4 |       uses: actions/setup-java@v3 | ||||||
|       with: |       with: | ||||||
|         distribution: temurin |         distribution: temurin | ||||||
|         java-version: 8 |         java-version: 8 | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       id: setup-gradle |  | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|         cache-read-only: false # For testing, allow writing cache entries on non-default branches |         cache-read-only: false # For testing, allow writing cache entries on non-default branches | ||||||
|         gradle-version: ${{ matrix.gradle }} |         gradle-version: ${{ matrix.gradle }} | ||||||
|     - name: Check output parameter |  | ||||||
|       if: ${{ steps.setup-gradle.outputs.gradle-version != matrix.gradle }} |  | ||||||
|       uses: actions/github-script@v7 |  | ||||||
|       with: |  | ||||||
|         script: | |  | ||||||
|           core.setFailed('Gradle version parameter not set correctly: value was "${{ steps.setup-gradle.outputs.gradle-version }}"')     |  | ||||||
|     - name: Run Gradle build |     - name: Run Gradle build | ||||||
|       id: gradle |       id: gradle | ||||||
|       working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} |       working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }} | ||||||
|       run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}" |       run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}" | ||||||
|     - name: Check Build Scan url |     - name: Check build scan url | ||||||
|       if: ${{ !steps.gradle.outputs.build-scan-url }} |       if: ${{ !steps.gradle.outputs.build-scan-url }} | ||||||
|       uses: actions/github-script@v7 |       uses: actions/github-script@v6 | ||||||
|       with: |       with: | ||||||
|         script: | |         script: | | ||||||
|           core.setFailed('No Build Scan detected')     |           core.setFailed('No build scan detected')     | ||||||
|    |    | ||||||
|     |     | ||||||
|  | |||||||
| @ -8,11 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|     secrets: |       download-dist: | ||||||
|       GRADLE_ENCRYPTION_KEY: |         type: boolean | ||||||
|         required: true |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-configuration-cache-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-configuration-cache-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -26,21 +27,16 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Java to ensure consistency |     - name: Download distribution if required | ||||||
|       uses: actions/setup-java@v4 |       uses: ./.github/actions/download-dist | ||||||
|       with: |  | ||||||
|         distribution: 'liberica' |  | ||||||
|         java-version: '21' |  | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|         cache-read-only: false # For testing, allow writing cache entries on non-default branches |         cache-read-only: false # For testing, allow writing cache entries on non-default branches | ||||||
|         cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
|         gradle-version: 8.6-rc-1 |  | ||||||
|     - name: Groovy build with configuration-cache enabled |     - name: Groovy build with configuration-cache enabled | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
|       run: gradle test --configuration-cache |       run: ./gradlew test --configuration-cache | ||||||
| 
 | 
 | ||||||
|   verify-build-groovy: |   verify-build-groovy: | ||||||
|     env: |     env: | ||||||
| @ -52,30 +48,23 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Java to ensure consistency |     - name: Download distribution if required | ||||||
|       uses: actions/setup-java@v4 |       uses: ./.github/actions/download-dist | ||||||
|       with: |  | ||||||
|         distribution: 'liberica' |  | ||||||
|         java-version: '21' |  | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|         cache-read-only: true |         cache-read-only: true | ||||||
|         cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
|         gradle-version: 8.6-rc-1 |  | ||||||
|     - name: Groovy build with configuration-cache enabled |     - name: Groovy build with configuration-cache enabled | ||||||
|       id: execute |       id: execute | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
|       run: gradle test --configuration-cache |       run: ./gradlew test --configuration-cache | ||||||
|     - name: Check that configuration-cache was used |     - name: Check that configuration-cache was used | ||||||
|       uses: actions/github-script@v7 |       if: ${{ steps.execute.outputs.task_configured == 'yes' }} | ||||||
|  |       uses: actions/github-script@v6 | ||||||
|       with: |       with: | ||||||
|         script: | |         script: | | ||||||
|           const fs = require('fs') |           core.setFailed('Configuration cache was not used - task was configured unexpectedly') | ||||||
|           if (fs.existsSync('.github/workflow-samples/groovy-dsl/task-configured.txt')) { |  | ||||||
|             core.setFailed('Configuration cache was not used - task was configured unexpectedly') |  | ||||||
|           } |  | ||||||
| 
 | 
 | ||||||
|   # Check that the build can run when no extracted cache entries are restored |   # Check that the build can run when no extracted cache entries are restored | ||||||
|   gradle-user-home-not-fully-restored: |   gradle-user-home-not-fully-restored: | ||||||
| @ -88,23 +77,18 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Java to ensure consistency |     - name: Download distribution if required | ||||||
|       uses: actions/setup-java@v4 |       uses: ./.github/actions/download-dist | ||||||
|       with: |  | ||||||
|         distribution: 'liberica' |  | ||||||
|         java-version: '21' |  | ||||||
|     - name: Setup Gradle with no extracted cache entries restored |     - name: Setup Gradle with no extracted cache entries restored | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       env:  |       env:  | ||||||
|         GRADLE_BUILD_ACTION_SKIP_RESTORE: "generated-gradle-jars|wrapper-zips|java-toolchains|instrumented-jars|dependencies|kotlin-dsl" |         GRADLE_BUILD_ACTION_SKIP_RESTORE: "generated-gradle-jars|wrapper-zips|java-toolchains|instrumented-jars|dependencies|kotlin-dsl" | ||||||
|       with: |       with: | ||||||
|         cache-read-only: true |         cache-read-only: true | ||||||
|         cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
|         gradle-version: 8.6-rc-1 |  | ||||||
|     - name: Check execute Gradle build with configuration cache enabled (but not restored) |     - name: Check execute Gradle build with configuration cache enabled (but not restored) | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
|       run: gradle test --configuration-cache |       run: ./gradlew test --configuration-cache | ||||||
| 
 | 
 | ||||||
|   seed-build-kotlin: |   seed-build-kotlin: | ||||||
|     env: |     env: | ||||||
| @ -115,21 +99,16 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Java to ensure consistency |     - name: Download distribution if required | ||||||
|       uses: actions/setup-java@v4 |       uses: ./.github/actions/download-dist | ||||||
|       with: |  | ||||||
|         distribution: 'liberica' |  | ||||||
|         java-version: '21' |  | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|         cache-read-only: false # For testing, allow writing cache entries on non-default branches |         cache-read-only: false # For testing, allow writing cache entries on non-default branches | ||||||
|         cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
|         gradle-version: 8.6-rc-1 |  | ||||||
|     - name: Execute 'help' with configuration-cache enabled |     - name: Execute 'help' with configuration-cache enabled | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: gradle help --configuration-cache |       run: ./gradlew help --configuration-cache | ||||||
| 
 | 
 | ||||||
|   modify-build-kotlin: |   modify-build-kotlin: | ||||||
|     env: |     env: | ||||||
| @ -141,21 +120,16 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Java to ensure consistency |     - name: Download distribution if required | ||||||
|       uses: actions/setup-java@v4 |       uses: ./.github/actions/download-dist | ||||||
|       with: |  | ||||||
|         distribution: 'liberica' |  | ||||||
|         java-version: '21' |  | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|         cache-read-only: false # For testing, allow writing cache entries on non-default branches |         cache-read-only: false # For testing, allow writing cache entries on non-default branches | ||||||
|         cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
|         gradle-version: 8.6-rc-1 |  | ||||||
|     - name: Execute 'test' with configuration-cache enabled |     - name: Execute 'test' with configuration-cache enabled | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: gradle test --configuration-cache |       run: ./gradlew test --configuration-cache | ||||||
| 
 | 
 | ||||||
|   # Test restore configuration-cache from the third build invocation |   # Test restore configuration-cache from the third build invocation | ||||||
|   verify-build-kotlin: |   verify-build-kotlin: | ||||||
| @ -168,28 +142,21 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|     - name: Setup Java to ensure consistency |     - name: Download distribution if required | ||||||
|       uses: actions/setup-java@v4 |       uses: ./.github/actions/download-dist | ||||||
|       with: |  | ||||||
|         distribution: 'liberica' |  | ||||||
|         java-version: '21' |  | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|         cache-read-only: true |         cache-read-only: true | ||||||
|         cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} |  | ||||||
|         gradle-version: 8.6-rc-1 |  | ||||||
|     - name: Execute 'test' again with configuration-cache enabled |     - name: Execute 'test' again with configuration-cache enabled | ||||||
|       id: execute |       id: execute | ||||||
|       working-directory: .github/workflow-samples/kotlin-dsl |       working-directory: .github/workflow-samples/kotlin-dsl | ||||||
|       run: gradle test --configuration-cache |       run: ./gradlew test --configuration-cache | ||||||
|     - name: Check that configuration-cache was used |     - name: Check that configuration-cache was used | ||||||
|       uses: actions/github-script@v7 |       if: ${{ steps.execute.outputs.task_configured == 'yes' }} | ||||||
|  |       uses: actions/github-script@v6 | ||||||
|       with: |       with: | ||||||
|         script: | |         script: | | ||||||
|           const fs = require('fs') |           core.setFailed('Configuration cache was not used - task was configured unexpectedly') | ||||||
|           if (fs.existsSync('.github/workflow-samples/kotlin-dsl/task-configured.txt')) { |  | ||||||
|             core.setFailed('Configuration cache was not used - task was configured unexpectedly') |  | ||||||
|           } |  | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,8 +5,12 @@ on: | |||||||
|     inputs: |     inputs: | ||||||
|       cache-key-prefix: |       cache-key-prefix: | ||||||
|         type: string |         type: string | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -16,9 +20,11 @@ jobs: | |||||||
|     container: fedora:latest |     container: fedora:latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Java |     - name: Setup Java | ||||||
|       uses: actions/setup-java@v4 |       uses: actions/setup-java@v3 | ||||||
|       with: |       with: | ||||||
|         java-version: 11 |         java-version: 11 | ||||||
|         distribution: temurin |         distribution: temurin | ||||||
| @ -37,9 +43,11 @@ jobs: | |||||||
|     container: fedora:latest |     container: fedora:latest | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Java |     - name: Setup Java | ||||||
|       uses: actions/setup-java@v4 |       uses: actions/setup-java@v3 | ||||||
|       with: |       with: | ||||||
|         java-version: 11 |         java-version: 11 | ||||||
|         distribution: temurin |         distribution: temurin | ||||||
|  | |||||||
| @ -5,8 +5,12 @@ on: | |||||||
|     inputs: |     inputs: | ||||||
|       cache-key-prefix: |       cache-key-prefix: | ||||||
|         type: string |         type: string | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -19,7 +23,9 @@ jobs: | |||||||
|         mkdir -p $GITHUB_WORKSPACE/gradle-user-home |         mkdir -p $GITHUB_WORKSPACE/gradle-user-home | ||||||
|         echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV |         echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -38,7 +44,9 @@ jobs: | |||||||
|         mkdir -p $GITHUB_WORKSPACE/gradle-user-home |         mkdir -p $GITHUB_WORKSPACE/gradle-user-home | ||||||
|         echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV |         echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -57,7 +65,9 @@ jobs: | |||||||
|         mkdir -p $GITHUB_WORKSPACE/gradle-user-home |         mkdir -p $GITHUB_WORKSPACE/gradle-user-home | ||||||
|         echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV |         echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|  | |||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-gradle-home-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-gradle-home-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-gradle-home |   GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-gradle-home | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| @ -22,7 +26,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -40,7 +46,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -58,7 +66,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -76,7 +86,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle with no extracted cache entries restored |     - name: Setup Gradle with no extracted cache entries restored | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       env:  |       env:  | ||||||
| @ -87,38 +99,3 @@ jobs: | |||||||
|       working-directory: .github/workflow-samples/groovy-dsl |       working-directory: .github/workflow-samples/groovy-dsl | ||||||
|       run: ./gradlew test |       run: ./gradlew test | ||||||
| 
 | 
 | ||||||
|   # Test that a pre-existing gradle-user-home can be overwritten by the restored cache |  | ||||||
|   pre-existing-gradle-home: |  | ||||||
|     needs: seed-build |  | ||||||
|     strategy: |  | ||||||
|       matrix: |  | ||||||
|         os: ${{fromJSON(inputs.runner-os)}} |  | ||||||
|     runs-on: ${{ matrix.os }} |  | ||||||
|     steps: |  | ||||||
|     - name: Checkout sources |  | ||||||
|       uses: actions/checkout@v4 |  | ||||||
|     - name: Pre-create Gradle User Home |  | ||||||
|       shell: bash |  | ||||||
|       run: | |  | ||||||
|         mkdir -p ~/.gradle/caches |  | ||||||
|         touch ~/.gradle/gradle.properties |  | ||||||
|         touch ~/.gradle/caches/dummy.txt |  | ||||||
|     - name: Setup Gradle |  | ||||||
|       uses: ./ |  | ||||||
|       with: |  | ||||||
|         cache-read-only: true |  | ||||||
|         cache-overwrite-existing: true |  | ||||||
|     - name: Check that pre-existing content still exists |  | ||||||
|       shell: bash |  | ||||||
|       run: | |  | ||||||
|         if [ ! -e ~/.gradle/caches/dummy.txt ]; then |  | ||||||
|           echo "::error ::Should find dummy.txt after cache restore" |  | ||||||
|           exit 1 |  | ||||||
|         fi |  | ||||||
|         if [ ! -e ~/.gradle/gradle.properties ]; then |  | ||||||
|           echo "::error ::Should find gradle.properties after cache restore" |  | ||||||
|           exit 1 |  | ||||||
|         fi |  | ||||||
|     - name: Execute Gradle build with --offline |  | ||||||
|       working-directory: .github/workflow-samples/groovy-dsl |  | ||||||
|       run: ./gradlew test --offline |  | ||||||
|  | |||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-java-toolchain-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-java-toolchain-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -39,7 +45,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|  | |||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-gradle-plugin-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-gradle-plugin-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -38,7 +44,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|  | |||||||
| @ -8,8 +8,12 @@ on: | |||||||
|       runner-os: |       runner-os: | ||||||
|         type: string |         type: string | ||||||
|         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' |         default: '["ubuntu-latest", "windows-latest", "macos-latest"]' | ||||||
|  |       download-dist: | ||||||
|  |         type: boolean | ||||||
|  |         default: false | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|  |   DOWNLOAD_DIST: ${{ inputs.download-dist }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-kotlin-dsl-${{ inputs.cache-key-prefix }} |   GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-kotlin-dsl-${{ inputs.cache-key-prefix }} | ||||||
|   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
| 
 | 
 | ||||||
| @ -21,7 +25,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
| @ -38,7 +44,9 @@ jobs: | |||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - name: Checkout sources | ||||||
|       uses: actions/checkout@v4 |       uses: actions/checkout@v3 | ||||||
|  |     - name: Download distribution if required | ||||||
|  |       uses: ./.github/actions/download-dist | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: ./ |       uses: ./ | ||||||
|       with: |       with: | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								.github/workflows/purge-old-workflow-runs.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.github/workflows/purge-old-workflow-runs.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | name: Purge old workflow runs | ||||||
|  | on: | ||||||
|  |   workflow_dispatch: | ||||||
|  |     inputs: | ||||||
|  |       days: | ||||||
|  |         description: 'Purge runs older than days' | ||||||
|  |         required: true | ||||||
|  |         default: 30 | ||||||
|  |       minimum_runs: | ||||||
|  |         description: 'The minimum runs to keep for each workflow.' | ||||||
|  |         required: true | ||||||
|  |         default: 6 | ||||||
|  |       delete_workflow_pattern: | ||||||
|  |         description: 'The name of the workflow. if not set then it will target all workflows.' | ||||||
|  |         required: false | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   del_runs: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Purge workflow runs | ||||||
|  |         uses: Mattraks/delete-workflow-runs@v2 | ||||||
|  |         with: | ||||||
|  |           token: ${{ github.token }} | ||||||
|  |           repository: ${{ github.repository }} | ||||||
|  |           retain_days: ${{ github.event.inputs.days }} | ||||||
|  |           keep_minimum_runs: ${{ github.event.inputs.minimum_runs }} | ||||||
|  |           delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }} | ||||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -102,3 +102,5 @@ __tests__/runner/* | |||||||
| .idea/ | .idea/ | ||||||
| *.iml | *.iml | ||||||
| 
 | 
 | ||||||
|  | # ASDF tool configuration | ||||||
|  | .tool-versions | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | dist/ | ||||||
|  | lib/ | ||||||
|  | node_modules/ | ||||||
							
								
								
									
										11
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | { | ||||||
|  |     "printWidth": 120, | ||||||
|  |     "tabWidth": 4, | ||||||
|  |     "useTabs": false, | ||||||
|  |     "semi": false, | ||||||
|  |     "singleQuote": true, | ||||||
|  |     "trailingComma": "none", | ||||||
|  |     "bracketSpacing": false, | ||||||
|  |     "arrowParens": "avoid", | ||||||
|  |     "parser": "typescript" | ||||||
|  |   } | ||||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | |||||||
| 
 | 
 | ||||||
| The MIT License (MIT) | The MIT License (MIT) | ||||||
| 
 | 
 | ||||||
| Copyright (c) 2023 Gradle Inc. | Copyright (c) 2018 GitHub, Inc. and contributors | ||||||
| 
 | 
 | ||||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
| of this software and associated documentation files (the "Software"), to deal | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | |||||||
							
								
								
									
										396
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										396
									
								
								README.md
									
									
									
									
									
								
							| @ -1,40 +1,378 @@ | |||||||
| > [!IMPORTANT] | # Execute Gradle builds in GitHub Actions workflows | ||||||
| > As of `v3` this action has been superceded by `gradle/actions/setup-gradle`. |  | ||||||
| > Any workflow that uses `gradle/gradle-build-action@v3` will transparently delegate to `gradle/actions/setup-gradle@v3`. |  | ||||||
| > |  | ||||||
| > Users are encouraged to update their workflows, replacing: |  | ||||||
| > ``` |  | ||||||
| > uses: gradle/gradle-build-action@v3 |  | ||||||
| > ``` |  | ||||||
| > |  | ||||||
| > with |  | ||||||
| > ``` |  | ||||||
| > uses: gradle/actions/setup-gradle@v3 |  | ||||||
| > ``` |  | ||||||
| > |  | ||||||
| > See the [setup-gradle documentation](https://github.com/gradle/actions/tree/main/setup-gradle) for up-to-date documentation for `gradle/actions/setup-gradle`.  |  | ||||||
| 
 | 
 | ||||||
| # Setup Gradle for use in GitHub Actions workflows | This GitHub Action can be used to configure Gradle and optionally execute a Gradle build on any platform supported by GitHub Actions. | ||||||
| 
 | 
 | ||||||
| This GitHub Action can be used to configure Gradle on any platform supported by GitHub Actions. | ## Use the action to setup Gradle | ||||||
| 
 | 
 | ||||||
| ## Example usage | If you have an existing workflow invoking Gradle, you can add an initial "Setup Gradle" Step to benefit from caching,  | ||||||
|  | build-scan capture and other features of the gradle-build-action. | ||||||
|  | 
 | ||||||
|  | All subsequent Gradle invocations will benefit from this initial setup, via `init` scripts added to the Gradle User Home. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| name: Build | name: Run Gradle on PRs | ||||||
| 
 | on: pull_request | ||||||
| on: [ push ] |  | ||||||
| 
 |  | ||||||
| jobs: | jobs: | ||||||
|   build: |   gradle: | ||||||
|     runs-on: ubuntu-latest |     strategy: | ||||||
|  |       matrix: | ||||||
|  |         os: [ubuntu-latest, macos-latest, windows-latest] | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout sources |     - uses: actions/checkout@v3 | ||||||
|       uses: actions/checkout@v4 |     - uses: actions/setup-java@v3 | ||||||
|  |       with: | ||||||
|  |         distribution: temurin | ||||||
|  |         java-version: 11 | ||||||
|  |          | ||||||
|     - name: Setup Gradle |     - name: Setup Gradle | ||||||
|       uses: gradle/actions/setup-gradle@v3 |       uses: gradle/gradle-build-action@v2 | ||||||
|     - name: Build with Gradle |      | ||||||
|  |     - name: Execute Gradle build | ||||||
|       run: ./gradlew build |       run: ./gradlew build | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| See the [full setup-gradle documentation](https://github.com/gradle/actions/tree/main/setup-gradle) for more advanced usage scenarios.  | ## Why use the `gradle-build-action`? | ||||||
|  | 
 | ||||||
|  | It is possible to directly invoke Gradle in your workflow, and the `actions/setup-java@v3` action provides a simple way to cache Gradle dependencies.  | ||||||
|  | 
 | ||||||
|  | However, the `gradle-build-action` offers a number of advantages over this approach: | ||||||
|  | 
 | ||||||
|  | - Easily [run the build with different versions of Gradle](#download-install-and-use-a-specific-gradle-version) using the `gradle-version` parameter. Gradle distributions are automatically downloaded and cached.  | ||||||
|  | - More sophisticated and more efficient caching of Gradle User Home between invocations, compared to `setup-java` and most custom configurations using `actions/cache`. [More details below](#caching). | ||||||
|  | - Detailed reporting of cache usage and cache configuration options allow you to [optimize the use of the GitHub actions cache](#optimizing-cache-effectiveness). | ||||||
|  | - [Automatic capture of build scan links](#build-scans) from the build, making these easier to locate for workflow run. | ||||||
|  | 
 | ||||||
|  | The `gradle-build-action` is designed to provide these benefits with minimal configuration.  | ||||||
|  | These features work both when Gradle is executed via the `gradle-build-action` and for any Gradle execution in subsequent steps. | ||||||
|  | 
 | ||||||
|  | When using `gradle-build-action` we recommend that you _not_ use `actions/cache` or `actions/setup-java@v3` to explicitly cache the Gradle User Home. Doing so may interfere with the caching provided by this action. | ||||||
|  | 
 | ||||||
|  | ## Use a specific Gradle version | ||||||
|  | 
 | ||||||
|  | The `gradle-build-action` can download and install a specified Gradle version, adding this installed version to the PATH. | ||||||
|  | Downloaded Gradle versions are stored in the GitHub Actions cache, to avoid requiring downloading again later. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  |  - uses: gradle/gradle-build-action@v2 | ||||||
|  |    with: | ||||||
|  |      gradle-version: 6.5 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | The `gradle-version` parameter can be set to any valid Gradle version. | ||||||
|  | 
 | ||||||
|  | Moreover, you can use the following aliases: | ||||||
|  | 
 | ||||||
|  | | Alias | Selects | | ||||||
|  | | --- |---| | ||||||
|  | | `wrapper`           | The Gradle wrapper's version (default, useful for matrix builds) | | ||||||
|  | | `current`           | The current [stable release](https://gradle.org/install/) | | ||||||
|  | | `release-candidate` | The current [release candidate](https://gradle.org/release-candidate/) if any, otherwise fallback to `current` | | ||||||
|  | | `nightly`           | The latest [nightly](https://gradle.org/nightly/), fails if none. | | ||||||
|  | | `release-nightly`   | The latest [release nightly](https://gradle.org/release-nightly/), fails if none.      | | ||||||
|  | 
 | ||||||
|  | This can be handy to automatically verify your build works with the latest release candidate of Gradle: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | name: Test latest Gradle RC | ||||||
|  | on: | ||||||
|  |   schedule: | ||||||
|  |     - cron: 0 0 * * * # daily | ||||||
|  | jobs: | ||||||
|  |   gradle-rc: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |     - uses: actions/setup-java@v3 | ||||||
|  |       with: | ||||||
|  |         distribution: temurin | ||||||
|  |         java-version: 11 | ||||||
|  |     - uses: gradle/gradle-build-action@v2 | ||||||
|  |       with: | ||||||
|  |         gradle-version: release-candidate | ||||||
|  |     - run: gradle build --dry-run # just test build configuration | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Gradle Execution | ||||||
|  | 
 | ||||||
|  | If the action is configured with an `arguments` input, then Gradle will execute a Gradle build with the arguments provided. | ||||||
|  | 
 | ||||||
|  | If no `arguments` are provided, the action will not execute Gradle, but will still cache Gradle state and configure build-scan capture for all subsequent Gradle executions. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | name: Run Gradle on PRs | ||||||
|  | on: pull_request | ||||||
|  | jobs: | ||||||
|  |   gradle: | ||||||
|  |     strategy: | ||||||
|  |       matrix: | ||||||
|  |         os: [ubuntu-latest, macos-latest, windows-latest] | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |     - uses: actions/setup-java@v3 | ||||||
|  |       with: | ||||||
|  |         distribution: temurin | ||||||
|  |         java-version: 11 | ||||||
|  |      | ||||||
|  |     - name: Setup and execute Gradle 'test' task | ||||||
|  |       uses: gradle/gradle-build-action@v2 | ||||||
|  |       with: | ||||||
|  |         arguments: test | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Multiple Gradle executions in the same Job | ||||||
|  | 
 | ||||||
|  | It is possible to configure multiple Gradle executions to run sequentially in the same job.  | ||||||
|  | The initial Action step will perform the Gradle setup. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | - uses: gradle/gradle-build-action@v2 | ||||||
|  |   with: | ||||||
|  |     arguments: assemble | ||||||
|  | - uses: gradle/gradle-build-action@v2 | ||||||
|  |   with: | ||||||
|  |     arguments: check | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Gradle command-line arguments | ||||||
|  | 
 | ||||||
|  | The `arguments` input can be 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 | ||||||
|  | arguments: build | ||||||
|  | arguments: check --scan | ||||||
|  | arguments: some arbitrary tasks | ||||||
|  | arguments: build -PgradleProperty=foo | ||||||
|  | arguments: | | ||||||
|  |     build | ||||||
|  |     --scan | ||||||
|  |     -PgradleProperty=foo | ||||||
|  |     -DsystemProperty=bar | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | If you need to pass environment variables, use the GitHub Actions workflow syntax: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | - uses: gradle/gradle-build-action@v2 | ||||||
|  |   env: | ||||||
|  |     CI: true | ||||||
|  |   with: | ||||||
|  |     arguments: build | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Gradle build located in a subdirectory | ||||||
|  | 
 | ||||||
|  | By default, the action will execute Gradle in the root directory of your project.  | ||||||
|  | Use the `build-root-directory` input to target a Gradle build in a subdirectory. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | - uses: gradle/gradle-build-action@v2 | ||||||
|  |   with: | ||||||
|  |     arguments: build | ||||||
|  |     build-root-directory: some/subdirectory | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Using a specific Gradle executable | ||||||
|  | 
 | ||||||
|  | The action will first look for a Gradle wrapper script in the root directory of your project.  | ||||||
|  | If not found, `gradle` will be executed from the PATH. | ||||||
|  | Use the `gradle-executable` input to execute using a specific Gradle installation. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  |  - uses: gradle/gradle-build-action@v2 | ||||||
|  |    with: | ||||||
|  |      arguments: build | ||||||
|  |      gradle-executable: /path/to/installed/gradle | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This mechanism can also be used to target a Gradle wrapper script that is located in a non-default location. | ||||||
|  | 
 | ||||||
|  | ## Caching | ||||||
|  | 
 | ||||||
|  | By default, this action aims to cache any and all reusable state that may be speed up a subsequent build invocation.  | ||||||
|  | 
 | ||||||
|  | The state that is cached includes: | ||||||
|  | - Any distributions downloaded to satisfy a `gradle-version` parameter ; | ||||||
|  | - A subset of the Gradle User Home directory, including downloaded dependencies, wrapper distributions, and the local build cache ; | ||||||
|  | - Any [configuration-cache](https://docs.gradle.org/nightly/userguide/configuration_cache.html) data stored in the project `.gradle` directory. (Only supported for Gradle 7 or higher.) | ||||||
|  | 
 | ||||||
|  | To reduce the space required for caching, this action makes a best effort to reduce duplication in cache entries. | ||||||
|  | 
 | ||||||
|  | Caching is enabled by default. You can disable caching for the action as follows: | ||||||
|  | ```yaml | ||||||
|  | cache-disabled: true | ||||||
|  | ``` | ||||||
|  | ### Cache keys | ||||||
|  | 
 | ||||||
|  | Distributions downloaded to satisfy a `gradle-version` parameter are stored outside of Gradle User Home and cached separately. The cache key is unique to the downloaded distribution and will not change over time. | ||||||
|  | 
 | ||||||
|  | The state of the Gradle User Home and configuration-cache are highly dependent on the Gradle execution, so the cache key is composed of the current commit hash and the GitHub actions job id. | ||||||
|  | As such, the cache key is likely to change on each subsequent run of GitHub actions.  | ||||||
|  | This allows the most recent state to always be available in the GitHub actions cache. | ||||||
|  | 
 | ||||||
|  | To reduce duplication between cache entries, certain artifacts are cached independently based on their identity. | ||||||
|  | Artifacts that are cached independently include downloaded dependencies, downloaded wrapper distributions and generated Gradle API jars. | ||||||
|  | For example, this means that all jobs executing a particular version of the Gradle wrapper will share common entries for wrapper distributions and for generated Gradle API jars. | ||||||
|  | 
 | ||||||
|  | ### Using the caches read-only | ||||||
|  | 
 | ||||||
|  | By default, the `gradle-build-action` will only write to the cache from Jobs on the default (`main`/`master`) branch. | ||||||
|  | Jobs on other branches will read entries from the cache but will not write updated entries.  | ||||||
|  | See [Optimizing cache effectiveness](#optimizing-cache-effectiveness) for a more detailed explanation. | ||||||
|  | 
 | ||||||
|  | In some circumstances it makes sense to change this default, and to configure a workflow Job to read existing cache entries but not to write changes back. | ||||||
|  | 
 | ||||||
|  | You can configure read-only caching for the `gradle-build-action` as follows: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | # Only write to the cache for builds on the 'main' and 'release' branches. (Default is 'main' only.) | ||||||
|  | # Builds on other branches will only read existing entries from the cache. | ||||||
|  | cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/release' }} | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Stopping the Gradle daemon | ||||||
|  | 
 | ||||||
|  | By default, the action will stop all running Gradle daemons in the post-action step, prior to saving the Gradle User Home state.  | ||||||
|  | This allows for any Gradle User Home cleanup to occur, and avoid file-locking issues on Windows. | ||||||
|  | 
 | ||||||
|  | If caching is unavailable or the cache is in read-only mode, the daemon will not be stopped and will continue running after the job is completed. | ||||||
|  | 
 | ||||||
|  | ### Gradle User Home cache tuning | ||||||
|  | 
 | ||||||
|  | As well as any wrapper distributions, the action will attempt to save and restore the `caches` and `notifications` directories from Gradle User Home. | ||||||
|  | 
 | ||||||
|  | The contents to be cached can be fine tuned by including and excluding certain paths with Gradle User Home. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | # Cache downloaded JDKs in addition to the default directories. | ||||||
|  | gradle-home-cache-includes: | | ||||||
|  |     caches | ||||||
|  |     notifications | ||||||
|  |     jdks | ||||||
|  | # Exclude the local build-cache from the directories cached. | ||||||
|  | gradle-home-cache-excludes: | | ||||||
|  |     caches/build-cache-1 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can specify any number of fixed paths or patterns to include or exclude.  | ||||||
|  | File pattern support is documented at https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#patterns-to-match-file-paths. | ||||||
|  | 
 | ||||||
|  | ### Cache debugging and analysis | ||||||
|  | 
 | ||||||
|  | Gradle User Home state will be restored from the cache during the first `gradle-build-action` step for any workflow job.  | ||||||
|  | This state will be saved back to the cache at the end of the job, after all Gradle executions have completed. | ||||||
|  | A report of all cache entries restored and saved is printed to the Job Summary when saving the cache entries.  | ||||||
|  | This report can provide valuable insignt into how much cache space is being used. | ||||||
|  | 
 | ||||||
|  | It is possible to enable additional debug logging for cache operations. You do via the `GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED` environment variable: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | env: | ||||||
|  |   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Note that this setting will also prevent certain cache operations from running in parallel, further assisting with debugging. | ||||||
|  | 
 | ||||||
|  | ### Optimizing cache effectiveness | ||||||
|  | 
 | ||||||
|  | Cache storage space for GitHub actions is limited, and writing new cache entries can trigger the deletion of existing entries. | ||||||
|  | Eviction of shared cache entries can reduce cache effectiveness, slowing down your `gradle-build-action` steps. | ||||||
|  | 
 | ||||||
|  | There are a number of actions you can take if your cache use is less effective due to entry eviction. | ||||||
|  | 
 | ||||||
|  | #### Select branches that should write to the cache | ||||||
|  | 
 | ||||||
|  | GitHub cache entries are not shared between builds on different branches.  | ||||||
|  | This means that each PR branch will have it's own Gradle User Home cache, and will not benefit from cache entries written by other PR branches. | ||||||
|  | An exception to this is that cache entries written in parent and upstream branches are visible to child branches, and cache entries for the default (`master`/`main`) branch can be read by actions invoked for any other branch. | ||||||
|  | 
 | ||||||
|  | By default, the `gradle-build-action` will only _write_ to the cache for builds run on the default (`master`/`main`) branch.  | ||||||
|  | Jobs run on other branches will only read from the cache. In most cases, this is the desired behaviour,  | ||||||
|  | because Jobs run against other branches will benefit from the cache Gradle User Home from `main`,  | ||||||
|  | without writing private cache entries that could lead to evicting shared entries. | ||||||
|  | 
 | ||||||
|  | If you have other long-lived development branches that would benefit from writing to the cache,  | ||||||
|  | you can configure these by overriding the `cache-read-only` action parameter.  | ||||||
|  | See [Using the caches read-only](#using-the-caches-read-only) for more details. | ||||||
|  | 
 | ||||||
|  | Similarly, you could use `cache-read-only` for certain jobs in the workflow, and instead have these jobs reuse the cache content from upstream jobs. | ||||||
|  | 
 | ||||||
|  | #### Exclude content from Gradle User Home cache | ||||||
|  | 
 | ||||||
|  | Each build is different, and some builds produce more Gradle User Home content than others. | ||||||
|  | [Cache debugging ](#cache-debugging-and-analysis) can provide insight into which cache entries are the largest, | ||||||
|  | and you can selectively [exclude content using `gradle-home-cache-exclude`](#gradle-user-home-cache-tuning). | ||||||
|  | 
 | ||||||
|  | ## Saving build outputs | ||||||
|  | 
 | ||||||
|  | By default, a GitHub Actions workflow using `gradle-build-action` will record the log output and any Build Scan links for your build, | ||||||
|  | but any output files generated by the build will not be saved. | ||||||
|  | 
 | ||||||
|  | To save selected files from your build execution, you can use the core [Upload-Artifact](https://github.com/actions/upload-artifact) action. | ||||||
|  | For example: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | jobs:    | ||||||
|  |   gradle: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout project sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: gradle/gradle-build-action@v2 | ||||||
|  |     - name: Run build with Gradle wrapper | ||||||
|  |       run: ./gradlew build --scan | ||||||
|  |     - name: Upload build reports | ||||||
|  |       uses: actions/upload-artifact@v3 | ||||||
|  |       with: | ||||||
|  |         name: build-reports | ||||||
|  |         path: build/reports/ | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Build scans | ||||||
|  | 
 | ||||||
|  | If your build publishes a [build scan](https://gradle.com/build-scans/) the `gradle-build-action` action will: | ||||||
|  | - Add a notice with the link to the GitHub Actions user interface | ||||||
|  | - For each step that executes Gradle, adds the link to the published build scan as a Step output named `build-scan-url`. | ||||||
|  | 
 | ||||||
|  | You can then use that link in subsequent actions of your workflow. For example: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | # .github/workflows/gradle-build-pr.yml | ||||||
|  | name: Run Gradle on PRs | ||||||
|  | on: pull_request | ||||||
|  | jobs: | ||||||
|  |   gradle: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout project sources | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |     - name: Setup Gradle | ||||||
|  |       uses: gradle/gradle-build-action@v2 | ||||||
|  |     - name: Run build with Gradle wrapper | ||||||
|  |       id: gradle | ||||||
|  |       run: ./gradlew build --scan | ||||||
|  |     - name: "Add build scan URL as PR comment" | ||||||
|  |       uses: actions/github-script@v5 | ||||||
|  |       if: github.event_name == 'pull_request' && failure() | ||||||
|  |       with: | ||||||
|  |         github-token: ${{secrets.GITHUB_TOKEN}} | ||||||
|  |         script: | | ||||||
|  |           github.rest.issues.createComment({ | ||||||
|  |             issue_number: context.issue.number, | ||||||
|  |             owner: context.repo.owner, | ||||||
|  |             repo: context.repo.repo, | ||||||
|  |             body: '❌ ${{ github.workflow }} failed: ${{ steps.gradle.outputs.build-scan-url }}' | ||||||
|  |           }) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Support for GitHub Enterprise Server (GHES) | ||||||
|  | 
 | ||||||
|  | You can use the `gradle-build-action` on GitHub Enterprise Server, and benefit from the improved integration with Gradle. Depending on the version of GHES you are running, certain features may be limited: | ||||||
|  | - Build scan links are captured and displayed in the GitHub Actions UI | ||||||
|  | - Easily run your build with different versions of Gradle | ||||||
|  | - Save/restore of Gradle User Home (requires GHES v3.5+ : GitHub Actions cache was introduced in GHES 3.5) | ||||||
|  | - Support for GitHub Actions Job Summary is not yet available in any version of GHES. Instead of producing a Job Summary, the build-results summary and caching report will be written to the workflow log, as part of the post-action step. | ||||||
|  | |||||||
							
								
								
									
										226
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										226
									
								
								action.yml
									
									
									
									
									
								
							| @ -1,14 +1,13 @@ | |||||||
| name: setup-gradle | name: "Gradle Build Action" | ||||||
| description: 'Configures Gradle for GitHub actions, caching state and generating a dependency graph via Dependency Submission.' | description: 'Configures Gradle for use in GitHub actions, caching useful state in the GitHub actions cache' | ||||||
|  | 
 | ||||||
|  | # https://help.github.com/en/articles/metadata-syntax-for-github-actions | ||||||
| 
 | 
 | ||||||
| inputs: | inputs: | ||||||
|   gradle-version: |   gradle-version: | ||||||
|     description: | |     description: Gradle version to use | ||||||
|       Gradle version to use. If specified, this Gradle version will be downloaded, added to the PATH and used for invoking Gradle. |  | ||||||
|       If not provided, it is assumed that the project uses the Gradle Wrapper. |  | ||||||
|     required: false |     required: false | ||||||
| 
 | 
 | ||||||
|   # Cache configuration |  | ||||||
|   cache-disabled: |   cache-disabled: | ||||||
|     description: When 'true', all caching is disabled. No entries will be written to or read from the cache. |     description: When 'true', all caching is disabled. No entries will be written to or read from the cache. | ||||||
|     required: false |     required: false | ||||||
| @ -28,18 +27,6 @@ inputs: | |||||||
|     required: false |     required: false | ||||||
|     default: false |     default: false | ||||||
| 
 | 
 | ||||||
|   cache-overwrite-existing: |  | ||||||
|     description: When 'true', a pre-existing Gradle User Home will not prevent the cache from being restored. |  | ||||||
|     required: false |  | ||||||
|     default: false |  | ||||||
| 
 |  | ||||||
|   cache-encryption-key: |  | ||||||
|     description: | |  | ||||||
|       A base64 encoded AES key used to encrypt the configuration-cache data. The key is exported as 'GRADLE_ENCRYPTION_KEY' for later steps. |  | ||||||
|       A suitable key can be generated with `openssl rand -base64 16`. |  | ||||||
|       Configuration-cache data will not be saved/restored without an encryption key being provided. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   gradle-home-cache-includes: |   gradle-home-cache-includes: | ||||||
|     description: Paths within Gradle User Home to cache. |     description: Paths within Gradle User Home to cache. | ||||||
|     required: false |     required: false | ||||||
| @ -50,219 +37,52 @@ inputs: | |||||||
|   gradle-home-cache-excludes: |   gradle-home-cache-excludes: | ||||||
|     description: Paths within Gradle User Home to exclude from cache. |     description: Paths within Gradle User Home to exclude from cache. | ||||||
|     required: false |     required: false | ||||||
|  |   # e.g. Use the following setting to prevent the local build cache from being saved/restored | ||||||
|  |   #      gradle-home-cache-excludes: | | ||||||
|  |   #           caches/build-cache-1 | ||||||
| 
 | 
 | ||||||
|   gradle-home-cache-cleanup: |   arguments: | ||||||
|     description: When 'true', the action will attempt to remove any stale/unused entries from the Gradle User Home prior to saving to the GitHub Actions cache. |     description: Gradle command line arguments (supports multi-line input) | ||||||
|     required: false |  | ||||||
|     default: false |  | ||||||
| 
 |  | ||||||
|   # Job summary configuration |  | ||||||
|   add-job-summary: |  | ||||||
|     description: Specifies when a Job Summary should be inluded in the action results. Valid values are 'never', 'always' (default), and 'on-failure'. |  | ||||||
|     required: false |  | ||||||
|     default: 'always' |  | ||||||
| 
 |  | ||||||
|   add-job-summary-as-pr-comment: |  | ||||||
|     description: Specifies when each Job Summary should be added as a PR comment. Valid values are 'never' (default), 'always', and 'on-failure'. No action will be taken if the workflow was not triggered from a pull request. |  | ||||||
|     required: false |  | ||||||
|     default: 'never' |  | ||||||
| 
 |  | ||||||
|   # Dependency Graph configuration |  | ||||||
|   dependency-graph: |  | ||||||
|     description: | |  | ||||||
|       Specifies if a GitHub dependency snapshot should be generated for each Gradle build, and if so, how. |  | ||||||
|       Valid values are 'disabled' (default), 'generate', 'generate-and-submit', 'generate-and-upload', 'download-and-submit' and 'clear'. |  | ||||||
|     required: false |  | ||||||
|     default: 'disabled' |  | ||||||
| 
 |  | ||||||
|   dependency-graph-continue-on-failure: |  | ||||||
|     description: When 'false' a failure to generate or submit a dependency graph will fail the Step or Job. When 'true' a warning will be emitted but no failure will result. |  | ||||||
|     required: false |  | ||||||
|     default: true |  | ||||||
| 
 |  | ||||||
|   artifact-retention-days: |  | ||||||
|     description: Specifies the number of days to retain any artifacts generated by the action. If not set, the default retention settings for the repository will apply. |  | ||||||
|     required: false |     required: false | ||||||
| 
 | 
 | ||||||
|   # Build Scan configuration |   build-root-directory: | ||||||
|   build-scan-publish: |     description: Path to the root directory of the build | ||||||
|     description: | |  | ||||||
|       Set to 'true' to automatically publish build results as a Build Scan on scans.gradle.com. |  | ||||||
|       For publication to succeed without user input, you must also provide values for `build-scan-terms-of-use-url` and 'build-scan-terms-of-use-agree'. |  | ||||||
|     required: false |  | ||||||
|     default: false |  | ||||||
| 
 |  | ||||||
|   build-scan-terms-of-use-url: |  | ||||||
|     description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service' or 'https://gradle.com/help/legal-terms-of-use'. |  | ||||||
|     required: false |     required: false | ||||||
| 
 | 
 | ||||||
|   build-scan-terms-of-use-agree: |   gradle-executable: | ||||||
|     description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes". |     description: Path to the Gradle executable | ||||||
|     required: false |     required: false | ||||||
| 
 | 
 | ||||||
|   develocity-access-key: |  | ||||||
|     description: Develocity access key. Should be set to a secret containing the Develocity Access key. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-token-expiry: |  | ||||||
|     description: The Develocity short-lived access tokens expiry in hours. Default is 2 hours. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-injection-enabled: |  | ||||||
|     description: Enables Develocity injection. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-url: |  | ||||||
|     description: The URL for the Develocity server. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-allow-untrusted-server: |  | ||||||
|     description: Allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-capture-file-fingerprints: |  | ||||||
|     description: Enables capturing the paths and content hashes of each individual input file. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-enforce-url: |  | ||||||
|     description: Enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-plugin-version: |  | ||||||
|     description: The version of the Develocity Gradle plugin to apply. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   develocity-ccud-plugin-version: |  | ||||||
|     description: The version of the Common Custom User Data Gradle plugin to apply, if any. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   gradle-plugin-repository-url: |  | ||||||
|     description: The URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   gradle-plugin-repository-username: |  | ||||||
|     description: The username for the repository URL to use when resolving the Develocity and CCUD. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   gradle-plugin-repository-password: |  | ||||||
|     description: The password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable. |  | ||||||
|     required: false |  | ||||||
| 
 |  | ||||||
|   # Wrapper validation configuration |  | ||||||
|   validate-wrappers: |  | ||||||
|     description: | |  | ||||||
|       When 'true', the action will perform the 'wrapper-validation' action automatically. |  | ||||||
|       If the wrapper checksums are not valid, the action will fail. |  | ||||||
|     required: false |  | ||||||
|     default: false |  | ||||||
| 
 |  | ||||||
|   # DEPRECATED ACTION INPUTS |  | ||||||
|   build-scan-terms-of-service-url: |  | ||||||
|     description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service'. |  | ||||||
|     required: false |  | ||||||
|     deprecation-message: The input has been renamed to align with the Develocity API. Use 'build-scan-terms-of-use-url' instead. |  | ||||||
| 
 |  | ||||||
|   build-scan-terms-of-service-agree: |  | ||||||
|     description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes". |  | ||||||
|     required: false |  | ||||||
|     deprecation-message: The input has been renamed to align with the Develocity API. Use 'build-scan-terms-of-use-agree' instead. |  | ||||||
| 
 |  | ||||||
|   generate-job-summary: |   generate-job-summary: | ||||||
|     description: When 'false', no Job Summary will be generated for the Job. |     description: When 'false', no Job Summary will be generated for the Job. | ||||||
|     required: false |     required: false | ||||||
|     default: true |     default: true | ||||||
|     deprecation-message: Superceded by the new 'add-job-summary' and 'add-job-summary-as-pr-comment' parameters. |  | ||||||
| 
 | 
 | ||||||
|   arguments: |   # EXPERIMENTAL & INTERNAL ACTION INPUTS | ||||||
|     description: Gradle command line arguments (supports multi-line input) |  | ||||||
|     required: false |  | ||||||
|     deprecation-message: Using the action to execute Gradle directly is deprecated in favor of using the action to setup Gradle, and executing Gradle in a subsequent Step. |  | ||||||
| 
 |  | ||||||
|   build-root-directory: |  | ||||||
|     description: Path to the root directory of the build. Default is the root of the GitHub workspace. |  | ||||||
|     required: false |  | ||||||
|     deprecation-message: Using the action to execute Gradle directly is deprecated in favor of using the action to setup Gradle, and executing Gradle in a subsequent Step. |  | ||||||
| 
 |  | ||||||
|   # EXPERIMENTAL ACTION INPUTS |  | ||||||
|   # The following action properties allow fine-grained tweaking of the action caching behaviour. |   # The following action properties allow fine-grained tweaking of the action caching behaviour. | ||||||
|   # These properties are experimental and not (yet) designed for production use, and may change without notice in a subsequent release of `setup-gradle`. |   # These properties are experimental and not (yet) designed for production use, and may change without notice in a subsequent release of `gradle-build-action`. | ||||||
|   # Use at your own risk! |   # Use at your own risk! | ||||||
|   gradle-home-cache-strict-match: |   gradle-home-cache-strict-match: | ||||||
|     description: When 'true', the action will not attempt to restore the Gradle User Home entries from other Jobs. |     description: When 'true', the action will not attempt to restore the Gradle User Home entries from other Jobs. | ||||||
|     required: false |     required: false | ||||||
|     default: false |     default: false | ||||||
| 
 |  | ||||||
|   # INTERNAL ACTION INPUTS |  | ||||||
|   # These inputs should not be configured directly, and are only used to pass environmental information to the action |  | ||||||
|   workflow-job-context: |   workflow-job-context: | ||||||
|     description: Used to uniquely identify the current job invocation. Defaults to the matrix values for this job; this should not be overridden by users (INTERNAL). |     description: Used to uniquely identify the current job invocation. Defaults to the matrix values for this job; this should not be overridden by users (INTERNAL). | ||||||
|     required: false |     required: false | ||||||
|     default: ${{ toJSON(matrix) }} |     default: ${{ toJSON(matrix) }} | ||||||
| 
 |   gradle-home-cache-cleanup: | ||||||
|   github-token: |     description: When 'true', the action will attempt to remove any stale/unused entries from the Gradle User Home prior to saving to the GitHub Actions cache. | ||||||
|     description: The GitHub token used to authenticate when submitting via the Dependency Submission API. |  | ||||||
|     default: ${{ github.token }} |  | ||||||
|     required: false |     required: false | ||||||
|  |     default: false | ||||||
| 
 | 
 | ||||||
| outputs: | outputs: | ||||||
|   build-scan-url: |   build-scan-url: | ||||||
|     description: Link to the Build Scan® generated by a Gradle build. Note that this output applies to a Step executing Gradle, not to the `setup-gradle` Step itself. |     description: Link to the build scan if any | ||||||
|     value: ${{ steps.setup-gradle.outputs.build-scan-url }} |  | ||||||
|   dependency-graph-file: |  | ||||||
|     description: Path to the GitHub Dependency Graph snapshot file generated by a Gradle build. Note that this output applies to a Step executing Gradle, not to the `setup-gradle` Step itself. |  | ||||||
|     value: ${{ steps.setup-gradle.outputs.dependency-graph-file }} |  | ||||||
|   gradle-version: |  | ||||||
|     description: Version of Gradle that was setup by the action |  | ||||||
|     value: ${{ steps.setup-gradle.outputs.gradle-version }} |  | ||||||
| 
 | 
 | ||||||
| runs: | runs: | ||||||
|   using: "composite" |   using: 'node16' | ||||||
|   steps: |   main: 'dist/main/index.js' | ||||||
|     - name: Setup Gradle |   post: 'dist/post/index.js' | ||||||
|       id: setup-gradle |  | ||||||
|       uses: gradle/actions/setup-gradle@v3.5.0 |  | ||||||
|       with: |  | ||||||
|         gradle-version: ${{ inputs.gradle-version }} |  | ||||||
|         cache-disabled: ${{ inputs.cache-disabled }} |  | ||||||
|         cache-read-only: ${{ inputs.cache-read-only }} |  | ||||||
|         cache-write-only: ${{ inputs.cache-write-only }} |  | ||||||
|         cache-overwrite-existing: ${{ inputs.cache-overwrite-existing }} |  | ||||||
|         cache-encryption-key: ${{ inputs.cache-encryption-key }} |  | ||||||
|         gradle-home-cache-includes: ${{ inputs.gradle-home-cache-includes }} |  | ||||||
|         gradle-home-cache-excludes: ${{ inputs.gradle-home-cache-excludes }} |  | ||||||
|         gradle-home-cache-cleanup: ${{ inputs.gradle-home-cache-cleanup }} |  | ||||||
|         add-job-summary: ${{ inputs.add-job-summary }} |  | ||||||
|         add-job-summary-as-pr-comment: ${{ inputs.add-job-summary-as-pr-comment }} |  | ||||||
|         dependency-graph: ${{ inputs.dependency-graph }} |  | ||||||
|         dependency-graph-continue-on-failure: ${{ inputs.dependency-graph-continue-on-failure }} |  | ||||||
|         artifact-retention-days: ${{ inputs.artifact-retention-days }} |  | ||||||
|         build-scan-publish: ${{ inputs.build-scan-publish }} |  | ||||||
|         build-scan-terms-of-use-url: ${{ inputs.build-scan-terms-of-use-url }} |  | ||||||
|         build-scan-terms-of-use-agree: ${{ inputs.build-scan-terms-of-use-agree }} |  | ||||||
|         validate-wrappers: ${{ inputs.validate-wrappers }} |  | ||||||
|         build-scan-terms-of-service-url: ${{ inputs.build-scan-terms-of-service-url }} |  | ||||||
|         build-scan-terms-of-service-agree: ${{ inputs.build-scan-terms-of-service-agree }} |  | ||||||
|         generate-job-summary: ${{ inputs.generate-job-summary }} |  | ||||||
|         arguments: ${{ inputs.arguments }} |  | ||||||
|         build-root-directory: ${{ inputs.build-root-directory }} |  | ||||||
|         gradle-home-cache-strict-match: ${{ inputs.gradle-home-cache-strict-match }} |  | ||||||
|         workflow-job-context: ${{ inputs.workflow-job-context }} |  | ||||||
|         github-token: ${{ inputs.github-token }} |  | ||||||
|         develocity-access-key: ${{ inputs.develocity-access-key }} |  | ||||||
|         develocity-token-expiry: ${{ inputs.develocity-token-expiry }} |  | ||||||
|         develocity-injection-enabled: ${{ inputs.develocity-injection-enabled }} |  | ||||||
|         develocity-url: ${{ inputs.develocity-url }} |  | ||||||
|         develocity-allow-untrusted-server: ${{ inputs.develocity-allow-untrusted-server }} |  | ||||||
|         develocity-capture-file-fingerprints: ${{ inputs.develocity-capture-file-fingerprints }} |  | ||||||
|         develocity-enforce-url: ${{ inputs.develocity-enforce-url }} |  | ||||||
|         develocity-plugin-version: ${{ inputs.develocity-plugin-version }} |  | ||||||
|         develocity-ccud-plugin-version: ${{ inputs.develocity-ccud-plugin-version }} |  | ||||||
|         gradle-plugin-repository-url: ${{ inputs.gradle-plugin-repository-url }} |  | ||||||
|         gradle-plugin-repository-username: ${{ inputs.gradle-plugin-repository-username }} |  | ||||||
|         gradle-plugin-repository-password: ${{ inputs.gradle-plugin-repository-password }} |  | ||||||
| 
 |  | ||||||
|       env: |  | ||||||
|         GRADLE_ACTION_ID: gradle/gradle-build-action |  | ||||||
| 
 | 
 | ||||||
| branding: | branding: | ||||||
|   icon: 'box' |   icon: 'box' | ||||||
|  | |||||||
							
								
								
									
										67757
									
								
								dist/main/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67757
									
								
								dist/main/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								dist/main/index.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/main/index.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								dist/main/sourcemap-register.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/main/sourcemap-register.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										66441
									
								
								dist/post/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66441
									
								
								dist/post/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								dist/post/index.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/post/index.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								dist/post/sourcemap-register.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/post/sourcemap-register.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										10
									
								
								jest.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								jest.config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | module.exports = { | ||||||
|  |   clearMocks: true, | ||||||
|  |   moduleFileExtensions: ['js', 'ts', 'json'], | ||||||
|  |   testEnvironment: 'node', | ||||||
|  |   testMatch: ['**/*.test.ts'], | ||||||
|  |   transform: { | ||||||
|  |     '^.+\\.ts$': 'ts-jest' | ||||||
|  |   }, | ||||||
|  |   verbose: true | ||||||
|  | } | ||||||
							
								
								
									
										12137
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12137
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										54
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | { | ||||||
|  |   "name": "gradle-build-action", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "private": true, | ||||||
|  |   "description": "Execute Gradle Build", | ||||||
|  |   "scripts": { | ||||||
|  |     "postinstall": "patch-package", | ||||||
|  |     "format": "prettier --write **/*.ts", | ||||||
|  |     "format-check": "prettier --check **/*.ts", | ||||||
|  |     "lint": "eslint src/**/*.ts", | ||||||
|  |     "compile": "ncc build src/main.ts --out dist/main --source-map && ncc build src/post.ts --out dist/post --source-map", | ||||||
|  |     "test": "jest", | ||||||
|  |     "check": "npm run format && npm run lint", | ||||||
|  |     "build": "npm run check && npm run compile", | ||||||
|  |     "all": "npm run build && npm test" | ||||||
|  |   }, | ||||||
|  |   "repository": { | ||||||
|  |     "type": "git", | ||||||
|  |     "url": "git+https://github.com/gradle/gradle-build-action.git" | ||||||
|  |   }, | ||||||
|  |   "keywords": [ | ||||||
|  |     "github", | ||||||
|  |     "actions", | ||||||
|  |     "github-actions", | ||||||
|  |     "gradle" | ||||||
|  |   ], | ||||||
|  |   "license": "MIT", | ||||||
|  |   "dependencies": { | ||||||
|  |     "@actions/cache": "3.0.4", | ||||||
|  |     "@actions/core": "1.9.1", | ||||||
|  |     "@actions/exec": "1.1.1", | ||||||
|  |     "@actions/github": "5.0.3", | ||||||
|  |     "@actions/glob": "0.3.0", | ||||||
|  |     "@actions/http-client": "2.0.1", | ||||||
|  |     "@actions/tool-cache": "2.0.1", | ||||||
|  |     "string-argv": "0.3.1" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "@types/jest": "28.1.7", | ||||||
|  |     "@types/node": "16.11.21", | ||||||
|  |     "@types/unzipper": "0.10.5", | ||||||
|  |     "@typescript-eslint/parser": "5.33.1", | ||||||
|  |     "@vercel/ncc": "0.34.0", | ||||||
|  |     "eslint": "8.22.0", | ||||||
|  |     "eslint-plugin-github": "4.3.7", | ||||||
|  |     "eslint-plugin-jest": "26.8.3", | ||||||
|  |     "jest": "28.1.3", | ||||||
|  |     "js-yaml": "4.1.0", | ||||||
|  |     "patch-package": "6.4.7", | ||||||
|  |     "prettier": "2.7.1", | ||||||
|  |     "ts-jest": "28.0.8", | ||||||
|  |     "typescript": "4.7.4" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										114
									
								
								patches/@actions+cache+3.0.4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								patches/@actions+cache+3.0.4.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | |||||||
|  | diff --git a/node_modules/@actions/cache/lib/cache.d.ts b/node_modules/@actions/cache/lib/cache.d.ts
 | ||||||
|  | index 16b20f7..aea77ba 100644
 | ||||||
|  | --- a/node_modules/@actions/cache/lib/cache.d.ts
 | ||||||
|  | +++ b/node_modules/@actions/cache/lib/cache.d.ts
 | ||||||
|  | @@ -20,7 +20,7 @@ export declare function isFeatureAvailable(): boolean;
 | ||||||
|  |   * @param downloadOptions cache download options | ||||||
|  |   * @returns string returns the key for the cache hit, otherwise returns undefined | ||||||
|  |   */ | ||||||
|  | -export declare function restoreCache(paths: string[], primaryKey: string, restoreKeys?: string[], options?: DownloadOptions): Promise<string | undefined>;
 | ||||||
|  | +export declare function restoreCache(paths: string[], primaryKey: string, restoreKeys?: string[], options?: DownloadOptions): Promise<CacheEntry | undefined>;
 | ||||||
|  |  /** | ||||||
|  |   * Saves a list of files with the specified key | ||||||
|  |   * | ||||||
|  | @@ -29,4 +29,12 @@ export declare function restoreCache(paths: string[], primaryKey: string, restor
 | ||||||
|  |   * @param options cache upload options | ||||||
|  |   * @returns number returns cacheId if the cache was saved successfully and throws an error if save fails | ||||||
|  |   */ | ||||||
|  | -export declare function saveCache(paths: string[], key: string, options?: UploadOptions): Promise<number>;
 | ||||||
|  | +export declare function saveCache(paths: string[], key: string, options?: UploadOptions): Promise<CacheEntry>;
 | ||||||
|  | +
 | ||||||
|  | +// PATCHED: Add `CacheEntry` as return type for save/restore functions
 | ||||||
|  | +// This allows us to track and report on cache entry sizes.
 | ||||||
|  | +export declare class CacheEntry {
 | ||||||
|  | +    key: string;
 | ||||||
|  | +    size?: number;
 | ||||||
|  | +    constructor(key: string, size?: number);
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/node_modules/@actions/cache/lib/cache.js b/node_modules/@actions/cache/lib/cache.js
 | ||||||
|  | index 4dc5e88..92d99d5 100644
 | ||||||
|  | --- a/node_modules/@actions/cache/lib/cache.js
 | ||||||
|  | +++ b/node_modules/@actions/cache/lib/cache.js
 | ||||||
|  | @@ -95,26 +95,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
 | ||||||
|  |              } | ||||||
|  |              archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); | ||||||
|  |              core.debug(`Archive Path: ${archivePath}`); | ||||||
|  | +            const restoredEntry = new CacheEntry(cacheEntry.cacheKey);
 | ||||||
|  |              // Download the cache from the cache entry | ||||||
|  |              yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); | ||||||
|  |              if (core.isDebug()) { | ||||||
|  |                  yield tar_1.listTar(archivePath, compressionMethod); | ||||||
|  |              } | ||||||
|  |              const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); | ||||||
|  | +            restoredEntry.size = archiveFileSize;
 | ||||||
|  |              core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); | ||||||
|  |              yield tar_1.extractTar(archivePath, compressionMethod); | ||||||
|  |              core.info('Cache restored successfully'); | ||||||
|  | -            return cacheEntry.cacheKey;
 | ||||||
|  | -        }
 | ||||||
|  | -        catch (error) {
 | ||||||
|  | -            const typedError = error;
 | ||||||
|  | -            if (typedError.name === ValidationError.name) {
 | ||||||
|  | -                throw error;
 | ||||||
|  | -            }
 | ||||||
|  | -            else {
 | ||||||
|  | -                // Supress all non-validation cache related errors because caching should be optional
 | ||||||
|  | -                core.warning(`Failed to restore: ${error.message}`);
 | ||||||
|  | -            }
 | ||||||
|  | +            return restoredEntry;
 | ||||||
|  |          } | ||||||
|  |          finally { | ||||||
|  |              // Try to delete the archive to save space | ||||||
|  | @@ -153,6 +145,7 @@ function saveCache(paths, key, options) {
 | ||||||
|  |          const archiveFolder = yield utils.createTempDirectory(); | ||||||
|  |          const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod)); | ||||||
|  |          core.debug(`Archive Path: ${archivePath}`); | ||||||
|  | +        const savedEntry = new CacheEntry(key);
 | ||||||
|  |          try { | ||||||
|  |              yield tar_1.createTar(archiveFolder, cachePaths, compressionMethod); | ||||||
|  |              if (core.isDebug()) { | ||||||
|  | @@ -160,6 +153,7 @@ function saveCache(paths, key, options) {
 | ||||||
|  |              } | ||||||
|  |              const fileSizeLimit = 10 * 1024 * 1024 * 1024; // 10GB per repo limit | ||||||
|  |              const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); | ||||||
|  | +            savedEntry.size = archiveFileSize;
 | ||||||
|  |              core.debug(`File Size: ${archiveFileSize}`); | ||||||
|  |              // For GHES, this check will take place in ReserveCache API with enterprise file size limit | ||||||
|  |              if (archiveFileSize > fileSizeLimit && !utils.isGhes()) { | ||||||
|  | @@ -182,18 +176,6 @@ function saveCache(paths, key, options) {
 | ||||||
|  |              core.debug(`Saving Cache (ID: ${cacheId})`); | ||||||
|  |              yield cacheHttpClient.saveCache(cacheId, archivePath, options); | ||||||
|  |          } | ||||||
|  | -        catch (error) {
 | ||||||
|  | -            const typedError = error;
 | ||||||
|  | -            if (typedError.name === ValidationError.name) {
 | ||||||
|  | -                throw error;
 | ||||||
|  | -            }
 | ||||||
|  | -            else if (typedError.name === ReserveCacheError.name) {
 | ||||||
|  | -                core.info(`Failed to save: ${typedError.message}`);
 | ||||||
|  | -            }
 | ||||||
|  | -            else {
 | ||||||
|  | -                core.warning(`Failed to save: ${typedError.message}`);
 | ||||||
|  | -            }
 | ||||||
|  | -        }
 | ||||||
|  |          finally { | ||||||
|  |              // Try to delete the archive to save space | ||||||
|  |              try { | ||||||
|  | @@ -203,8 +185,15 @@ function saveCache(paths, key, options) {
 | ||||||
|  |                  core.debug(`Failed to delete archive: ${error}`); | ||||||
|  |              } | ||||||
|  |          } | ||||||
|  | -        return cacheId;
 | ||||||
|  | +        return savedEntry;
 | ||||||
|  |      }); | ||||||
|  |  } | ||||||
|  |  exports.saveCache = saveCache; | ||||||
|  | +class CacheEntry {
 | ||||||
|  | +    constructor(key, size) {
 | ||||||
|  | +        this.key = key;
 | ||||||
|  | +        this.size = size;
 | ||||||
|  | +    }
 | ||||||
|  | +}
 | ||||||
|  | +exports.CacheEntry = CacheEntry;
 | ||||||
|  |  //# sourceMappingURL=cache.js.map | ||||||
|  | \ No newline at end of file | ||||||
							
								
								
									
										0
									
								
								release/changes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								release/changes.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										27
									
								
								src/build-results.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/build-results.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | import * as fs from 'fs' | ||||||
|  | import * as path from 'path' | ||||||
|  | 
 | ||||||
|  | export interface BuildResult { | ||||||
|  |     get rootProjectName(): string | ||||||
|  |     get rootProjectDir(): string | ||||||
|  |     get requestedTasks(): string | ||||||
|  |     get gradleVersion(): string | ||||||
|  |     get gradleHomeDir(): string | ||||||
|  |     get buildFailed(): boolean | ||||||
|  |     get buildScanUri(): string | ||||||
|  |     get buildScanFailed(): boolean | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function loadBuildResults(): BuildResult[] { | ||||||
|  |     const buildResultsDir = path.resolve(process.env['RUNNER_TEMP']!, '.build-results') | ||||||
|  |     if (!fs.existsSync(buildResultsDir)) { | ||||||
|  |         return [] | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return fs.readdirSync(buildResultsDir).map(file => { | ||||||
|  |         // Every file in the .build-results dir should be a BuildResults JSON
 | ||||||
|  |         const filePath = path.join(buildResultsDir, file) | ||||||
|  |         const content = fs.readFileSync(filePath, 'utf8') | ||||||
|  |         return JSON.parse(content) as BuildResult | ||||||
|  |     }) | ||||||
|  | } | ||||||
							
								
								
									
										222
									
								
								src/cache-base.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								src/cache-base.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,222 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as exec from '@actions/exec' | ||||||
|  | import path from 'path' | ||||||
|  | import fs from 'fs' | ||||||
|  | import {CacheListener} from './cache-reporting' | ||||||
|  | import {saveCache, restoreCache, cacheDebug, isCacheDebuggingEnabled, tryDelete, generateCacheKey} from './cache-utils' | ||||||
|  | import {ConfigurationCacheEntryExtractor, 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 | ||||||
|  |     private cacheDescription: string | ||||||
|  | 
 | ||||||
|  |     protected readonly gradleUserHome: string | ||||||
|  | 
 | ||||||
|  |     constructor(gradleUserHome: string) { | ||||||
|  |         this.gradleUserHome = gradleUserHome | ||||||
|  |         this.cacheName = 'gradle' | ||||||
|  |         this.cacheDescription = 'Gradle User Home' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     init(): void { | ||||||
|  |         const actionCacheDir = path.resolve(this.gradleUserHome, '.gradle-build-action') | ||||||
|  |         fs.mkdirSync(actionCacheDir, {recursive: true}) | ||||||
|  | 
 | ||||||
|  |         const initScriptsDir = path.resolve(this.gradleUserHome, 'init.d') | ||||||
|  |         fs.mkdirSync(initScriptsDir, {recursive: true}) | ||||||
|  | 
 | ||||||
|  |         this.initializeGradleUserHome(this.gradleUserHome, initScriptsDir) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     cacheOutputExists(): boolean { | ||||||
|  |         const cachesDir = path.resolve(this.gradleUserHome, 'caches') | ||||||
|  |         if (fs.existsSync(cachesDir)) { | ||||||
|  |             cacheDebug(`Cache output exists at ${cachesDir}`) | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |         return false | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Restores the cache entry, finding the closest match to the currently running job. | ||||||
|  |      */ | ||||||
|  |     async restore(listener: CacheListener): Promise<void> { | ||||||
|  |         const entryListener = listener.entry(this.cacheDescription) | ||||||
|  | 
 | ||||||
|  |         const cacheKey = generateCacheKey(this.cacheName) | ||||||
|  | 
 | ||||||
|  |         cacheDebug( | ||||||
|  |             `Requesting ${this.cacheDescription} with
 | ||||||
|  |     key:${cacheKey.key} | ||||||
|  |     restoreKeys:[${cacheKey.restoreKeys}]` | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         const cacheResult = await restoreCache(this.getCachePath(), cacheKey.key, cacheKey.restoreKeys, entryListener) | ||||||
|  |         if (!cacheResult) { | ||||||
|  |             core.info(`${this.cacheDescription} cache not found. Will initialize empty.`) | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         core.saveState(RESTORED_CACHE_KEY_KEY, cacheResult.key) | ||||||
|  | 
 | ||||||
|  |         core.info(`Restored ${this.cacheDescription} from cache key: ${cacheResult.key}`) | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             await this.afterRestore(listener) | ||||||
|  |         } catch (error) { | ||||||
|  |             core.warning(`Restore ${this.cacheDescription} failed in 'afterRestore': ${error}`) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Restore any extracted cache entries after the main Gradle User Home entry is restored. | ||||||
|  |      */ | ||||||
|  |     async afterRestore(listener: CacheListener): Promise<void> { | ||||||
|  |         await this.debugReportGradleUserHomeSize('as restored from cache') | ||||||
|  |         await new GradleHomeEntryExtractor(this.gradleUserHome).restore(listener) | ||||||
|  |         await new ConfigurationCacheEntryExtractor(this.gradleUserHome).restore(listener) | ||||||
|  |         await this.debugReportGradleUserHomeSize('after restoring common artifacts') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Saves the cache entry based on the current cache key unless the cache was restored with the exact key, | ||||||
|  |      * in which case we cannot overwrite it. | ||||||
|  |      * | ||||||
|  |      * If the cache entry was restored with a partial match on a restore key, then | ||||||
|  |      * it is saved with the exact key. | ||||||
|  |      */ | ||||||
|  |     async save(listener: CacheListener): Promise<void> { | ||||||
|  |         const cacheKey = generateCacheKey(this.cacheName).key | ||||||
|  |         const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY) | ||||||
|  |         const gradleHomeEntryListener = listener.entry(this.cacheDescription) | ||||||
|  | 
 | ||||||
|  |         if (restoredCacheKey && cacheKey === restoredCacheKey) { | ||||||
|  |             core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`) | ||||||
|  | 
 | ||||||
|  |             for (const entryListener of listener.cacheEntries) { | ||||||
|  |                 if (entryListener === gradleHomeEntryListener) { | ||||||
|  |                     entryListener.markNotSaved('cache key not changed') | ||||||
|  |                 } else { | ||||||
|  |                     entryListener.markNotSaved(`referencing '${this.cacheDescription}' cache entry not saved`) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             await this.beforeSave(listener) | ||||||
|  |         } catch (error) { | ||||||
|  |             core.warning(`Save ${this.cacheDescription} failed in 'beforeSave': ${error}`) | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`) | ||||||
|  |         const cachePath = this.getCachePath() | ||||||
|  |         await saveCache(cachePath, cacheKey, gradleHomeEntryListener) | ||||||
|  | 
 | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Extract and save any defined extracted cache entries prior to the main Gradle User Home entry being saved. | ||||||
|  |      */ | ||||||
|  |     async beforeSave(listener: CacheListener): Promise<void> { | ||||||
|  |         await this.debugReportGradleUserHomeSize('before saving common artifacts') | ||||||
|  |         this.deleteExcludedPaths() | ||||||
|  |         await Promise.all([ | ||||||
|  |             new GradleHomeEntryExtractor(this.gradleUserHome).extract(listener), | ||||||
|  |             new ConfigurationCacheEntryExtractor(this.gradleUserHome).extract(listener) | ||||||
|  |         ]) | ||||||
|  |         await this.debugReportGradleUserHomeSize( | ||||||
|  |             "after extracting common artifacts (only 'caches' and 'notifications' will be stored)" | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 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 resolvedPaths = rawPaths.map(x => path.resolve(this.gradleUserHome, x)) | ||||||
|  | 
 | ||||||
|  |         for (const p of resolvedPaths) { | ||||||
|  |             cacheDebug(`Deleting excluded path: ${p}`) | ||||||
|  |             tryDelete(p) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determines the paths within Gradle User Home to cache. | ||||||
|  |      * By default, this is the 'caches' and 'notifications' directories, | ||||||
|  |      * but this can be overridden by the `gradle-home-cache-includes` parameter. | ||||||
|  |      */ | ||||||
|  |     protected getCachePath(): string[] { | ||||||
|  |         const rawPaths: string[] = core.getMultilineInput(INCLUDE_PATHS_PARAMETER) | ||||||
|  |         rawPaths.push(META_FILE_DIR) | ||||||
|  |         const resolvedPaths = rawPaths.map(x => this.resolveCachePath(x)) | ||||||
|  |         cacheDebug(`Using cache paths: ${resolvedPaths}`) | ||||||
|  |         return resolvedPaths | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private resolveCachePath(rawPath: string): string { | ||||||
|  |         if (rawPath.startsWith('!')) { | ||||||
|  |             const resolved = this.resolveCachePath(rawPath.substring(1)) | ||||||
|  |             return `!${resolved}` | ||||||
|  |         } | ||||||
|  |         return path.resolve(this.gradleUserHome, rawPath) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private initializeGradleUserHome(gradleUserHome: string, initScriptsDir: string): void { | ||||||
|  |         const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'] | ||||||
|  |         for (const initScriptFilename of initScriptFilenames) { | ||||||
|  |             const initScriptContent = this.readInitScriptAsString(initScriptFilename) | ||||||
|  |             const initScriptPath = path.resolve(initScriptsDir, initScriptFilename) | ||||||
|  |             fs.writeFileSync(initScriptPath, initScriptContent) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private readInitScriptAsString(resource: string): string { | ||||||
|  |         // Resolving relative to __dirname will allow node to find the resource at runtime
 | ||||||
|  |         const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource) | ||||||
|  |         return fs.readFileSync(absolutePath, 'utf8') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * When cache debugging is enabled, this method will give a detailed report | ||||||
|  |      * of the Gradle User Home contents. | ||||||
|  |      */ | ||||||
|  |     private async debugReportGradleUserHomeSize(label: string): Promise<void> { | ||||||
|  |         if (!isCacheDebuggingEnabled()) { | ||||||
|  |             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('-----------------------') | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										59
									
								
								src/cache-cleaner.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/cache-cleaner.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | import * as exec from '@actions/exec' | ||||||
|  | import fs from 'fs' | ||||||
|  | import path from 'path' | ||||||
|  | 
 | ||||||
|  | export class CacheCleaner { | ||||||
|  |     private readonly gradleUserHome: string | ||||||
|  |     private readonly tmpDir: string | ||||||
|  | 
 | ||||||
|  |     constructor(gradleUserHome: string, tmpDir: string) { | ||||||
|  |         this.gradleUserHome = gradleUserHome | ||||||
|  |         this.tmpDir = tmpDir | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async prepare(): Promise<void> { | ||||||
|  |         // Reset the file-access journal so that files appear not to have been used recently
 | ||||||
|  |         fs.rmSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true, force: true}) | ||||||
|  |         fs.mkdirSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true}) | ||||||
|  |         fs.writeFileSync( | ||||||
|  |             path.resolve(this.gradleUserHome, 'caches/journal-1/file-access.properties'), | ||||||
|  |             'inceptionTimestamp=0' | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         // Set the modification time of all files to the past: this timestamp is used when there is no matching entry in the journal
 | ||||||
|  |         await this.ageAllFiles() | ||||||
|  | 
 | ||||||
|  |         // Touch all 'gc' files so that cache cleanup won't run immediately.
 | ||||||
|  |         await this.touchAllFiles('gc.properties') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async forceCleanup(): Promise<void> { | ||||||
|  |         // Age all 'gc' files so that cache cleanup will run immediately.
 | ||||||
|  |         await this.ageAllFiles('gc.properties') | ||||||
|  | 
 | ||||||
|  |         // Run a dummy Gradle build to trigger cache cleanup
 | ||||||
|  |         const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project') | ||||||
|  |         fs.mkdirSync(cleanupProjectDir, {recursive: true}) | ||||||
|  |         fs.writeFileSync( | ||||||
|  |             path.resolve(cleanupProjectDir, 'settings.gradle'), | ||||||
|  |             'rootProject.name = "dummy-cleanup-project"' | ||||||
|  |         ) | ||||||
|  |         fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}') | ||||||
|  | 
 | ||||||
|  |         await exec.exec(`gradle -g ${this.gradleUserHome} --no-daemon --build-cache --no-scan --quiet noop`, [], { | ||||||
|  |             cwd: cleanupProjectDir | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async ageAllFiles(fileName = '*'): Promise<void> { | ||||||
|  |         await exec.exec( | ||||||
|  |             'find', | ||||||
|  |             [this.gradleUserHome, '-name', fileName, '-exec', 'touch', '-m', '-d', '1970-01-01', '{}', '+'], | ||||||
|  |             {} | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async touchAllFiles(fileName = '*'): Promise<void> { | ||||||
|  |         await exec.exec('find', [this.gradleUserHome, '-name', fileName, '-exec', 'touch', '-m', '{}', '+'], {}) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										393
									
								
								src/cache-extract-entries.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								src/cache-extract-entries.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,393 @@ | |||||||
|  | import path from 'path' | ||||||
|  | import fs from 'fs' | ||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as glob from '@actions/glob' | ||||||
|  | 
 | ||||||
|  | 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 {loadBuildResults} from './build-results' | ||||||
|  | 
 | ||||||
|  | const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE' | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Represents the result of attempting to load or store an extracted cache entry. | ||||||
|  |  * An undefined cacheKey indicates that the operation did not succeed. | ||||||
|  |  * The collected results are then used to populate the `cache-metadata.json` file for later use. | ||||||
|  |  */ | ||||||
|  | class ExtractedCacheEntry { | ||||||
|  |     artifactType: string | ||||||
|  |     pattern: string | ||||||
|  |     cacheKey: string | undefined | ||||||
|  | 
 | ||||||
|  |     constructor(artifactType: string, pattern: string, cacheKey: string | undefined) { | ||||||
|  |         this.artifactType = artifactType | ||||||
|  |         this.pattern = pattern | ||||||
|  |         this.cacheKey = cacheKey | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Representation of all of the extracted cache entries for this Gradle User Home. | ||||||
|  |  * This object is persisted to JSON file in the Gradle User Home directory for storing, | ||||||
|  |  * and subsequently used to restore the Gradle User Home. | ||||||
|  |  */ | ||||||
|  | class ExtractedCacheEntryMetadata { | ||||||
|  |     entries: ExtractedCacheEntry[] = [] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * The specification for a type of extracted cache entry. | ||||||
|  |  */ | ||||||
|  | class ExtractedCacheEntryDefinition { | ||||||
|  |     artifactType: string | ||||||
|  |     pattern: string | ||||||
|  |     bundle: boolean | ||||||
|  |     uniqueFileNames = true | ||||||
|  | 
 | ||||||
|  |     constructor(artifactType: string, pattern: string, bundle: boolean) { | ||||||
|  |         this.artifactType = artifactType | ||||||
|  |         this.pattern = pattern | ||||||
|  |         this.bundle = bundle | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     withNonUniqueFileNames(): ExtractedCacheEntryDefinition { | ||||||
|  |         this.uniqueFileNames = false | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Caches and restores the entire Gradle User Home directory, extracting entries containing common artifacts | ||||||
|  |  * for more efficient storage. | ||||||
|  |  */ | ||||||
|  | abstract class AbstractEntryExtractor { | ||||||
|  |     protected readonly gradleUserHome: string | ||||||
|  |     private extractorName: string | ||||||
|  | 
 | ||||||
|  |     constructor(gradleUserHome: string, extractorName: string) { | ||||||
|  |         this.gradleUserHome = gradleUserHome | ||||||
|  |         this.extractorName = extractorName | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Restores any artifacts that were cached separately, based on the information in the `cache-metadata.json` file. | ||||||
|  |      * Each extracted cache entry is restored in parallel, except when debugging is enabled. | ||||||
|  |      */ | ||||||
|  |     async restore(listener: CacheListener): Promise<void> { | ||||||
|  |         const previouslyExtractedCacheEntries = this.loadExtractedCacheEntries() | ||||||
|  | 
 | ||||||
|  |         const processes: Promise<ExtractedCacheEntry>[] = [] | ||||||
|  | 
 | ||||||
|  |         for (const cacheEntry of previouslyExtractedCacheEntries) { | ||||||
|  |             const artifactType = cacheEntry.artifactType | ||||||
|  |             const entryListener = listener.entry(cacheEntry.pattern) | ||||||
|  | 
 | ||||||
|  |             // Handle case where the extracted-cache-entry definitions have been changed
 | ||||||
|  |             const skipRestore = process.env[SKIP_RESTORE_VAR] || '' | ||||||
|  |             if (skipRestore.includes(artifactType)) { | ||||||
|  |                 core.info(`Not restoring extracted cache entry for ${artifactType}`) | ||||||
|  |                 entryListener.markRequested('SKIP_RESTORE') | ||||||
|  |             } else { | ||||||
|  |                 processes.push( | ||||||
|  |                     this.awaitForDebugging( | ||||||
|  |                         this.restoreExtractedCacheEntry( | ||||||
|  |                             artifactType, | ||||||
|  |                             cacheEntry.cacheKey!, | ||||||
|  |                             cacheEntry.pattern, | ||||||
|  |                             entryListener | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.saveMetadataForCacheResults(await Promise.all(processes)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async restoreExtractedCacheEntry( | ||||||
|  |         artifactType: string, | ||||||
|  |         cacheKey: string, | ||||||
|  |         pattern: string, | ||||||
|  |         listener: CacheEntryListener | ||||||
|  |     ): Promise<ExtractedCacheEntry> { | ||||||
|  |         const restoredEntry = await restoreCache([pattern], cacheKey, [], listener) | ||||||
|  |         if (restoredEntry) { | ||||||
|  |             core.info(`Restored ${artifactType} with key ${cacheKey} to ${pattern}`) | ||||||
|  |             return new ExtractedCacheEntry(artifactType, pattern, cacheKey) | ||||||
|  |         } else { | ||||||
|  |             core.info(`Did not restore ${artifactType} with key ${cacheKey} to ${pattern}`) | ||||||
|  |             return new ExtractedCacheEntry(artifactType, pattern, undefined) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Saves any artifacts that are configured to be cached separately, based on the extracted cache entry definitions. | ||||||
|  |      * Each entry is extracted and saved in parallel, except when debugging is enabled. | ||||||
|  |      */ | ||||||
|  |     async extract(listener: CacheListener): Promise<void> { | ||||||
|  |         // Load the cache entry definitions (from config) and the previously restored entries (from persisted metadata file)
 | ||||||
|  |         const cacheEntryDefinitions = this.getExtractedCacheEntryDefinitions() | ||||||
|  |         cacheDebug( | ||||||
|  |             `Extracting cache entries for ${this.extractorName}: ${JSON.stringify(cacheEntryDefinitions, null, 2)}` | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         const previouslyRestoredEntries = this.loadExtractedCacheEntries() | ||||||
|  |         const cacheActions: Promise<ExtractedCacheEntry>[] = [] | ||||||
|  | 
 | ||||||
|  |         // For each cache entry definition, determine if it has already been restored, and if not, extract it
 | ||||||
|  |         for (const cacheEntryDefinition of cacheEntryDefinitions) { | ||||||
|  |             const artifactType = cacheEntryDefinition.artifactType | ||||||
|  |             const pattern = cacheEntryDefinition.pattern | ||||||
|  | 
 | ||||||
|  |             // Find all matching files for this cache entry definition
 | ||||||
|  |             const globber = await glob.create(pattern, { | ||||||
|  |                 implicitDescendants: false | ||||||
|  |             }) | ||||||
|  |             const matchingFiles = await globber.glob() | ||||||
|  | 
 | ||||||
|  |             if (matchingFiles.length === 0) { | ||||||
|  |                 cacheDebug(`No files found to cache for ${artifactType}`) | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (cacheEntryDefinition.bundle) { | ||||||
|  |                 // For an extracted "bundle", use the defined pattern and cache all matching files in a single entry.
 | ||||||
|  |                 cacheActions.push( | ||||||
|  |                     this.awaitForDebugging( | ||||||
|  |                         this.saveExtractedCacheEntry( | ||||||
|  |                             matchingFiles, | ||||||
|  |                             artifactType, | ||||||
|  |                             pattern, | ||||||
|  |                             cacheEntryDefinition.uniqueFileNames, | ||||||
|  |                             previouslyRestoredEntries, | ||||||
|  |                             listener.entry(pattern) | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |             } else { | ||||||
|  |                 // Otherwise cache each matching file in a separate entry, using the complete file path as the cache pattern.
 | ||||||
|  |                 for (const cacheFile of matchingFiles) { | ||||||
|  |                     cacheActions.push( | ||||||
|  |                         this.awaitForDebugging( | ||||||
|  |                             this.saveExtractedCacheEntry( | ||||||
|  |                                 [cacheFile], | ||||||
|  |                                 artifactType, | ||||||
|  |                                 cacheFile, | ||||||
|  |                                 cacheEntryDefinition.uniqueFileNames, | ||||||
|  |                                 previouslyRestoredEntries, | ||||||
|  |                                 listener.entry(cacheFile) | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.saveMetadataForCacheResults(await Promise.all(cacheActions)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async saveExtractedCacheEntry( | ||||||
|  |         matchingFiles: string[], | ||||||
|  |         artifactType: string, | ||||||
|  |         pattern: string, | ||||||
|  |         uniqueFileNames: boolean, | ||||||
|  |         previouslyRestoredEntries: ExtractedCacheEntry[], | ||||||
|  |         entryListener: CacheEntryListener | ||||||
|  |     ): Promise<ExtractedCacheEntry> { | ||||||
|  |         const cacheKey = uniqueFileNames | ||||||
|  |             ? this.createCacheKeyFromFileNames(artifactType, matchingFiles) | ||||||
|  |             : await this.createCacheKeyFromFileContents(artifactType, pattern) | ||||||
|  |         const previouslyRestoredKey = previouslyRestoredEntries.find( | ||||||
|  |             x => x.artifactType === artifactType && x.pattern === pattern | ||||||
|  |         )?.cacheKey | ||||||
|  | 
 | ||||||
|  |         if (previouslyRestoredKey === cacheKey) { | ||||||
|  |             cacheDebug(`No change to previously restored ${artifactType}. Not saving.`) | ||||||
|  |             entryListener.markNotSaved('contents unchanged') | ||||||
|  |         } else { | ||||||
|  |             core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`) | ||||||
|  |             await saveCache([pattern], cacheKey, entryListener) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for (const file of matchingFiles) { | ||||||
|  |             tryDelete(file) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return new ExtractedCacheEntry(artifactType, pattern, cacheKey) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected createCacheKeyFromFileNames(artifactType: string, files: string[]): string { | ||||||
|  |         const cacheKeyPrefix = getCacheKeyPrefix() | ||||||
|  |         const relativeFiles = files.map(x => path.relative(this.gradleUserHome, x)) | ||||||
|  |         const key = hashFileNames(relativeFiles) | ||||||
|  | 
 | ||||||
|  |         cacheDebug(`Generating cache key for ${artifactType} from file names: ${relativeFiles}`) | ||||||
|  | 
 | ||||||
|  |         return `${cacheKeyPrefix}${artifactType}-${key}` | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected async createCacheKeyFromFileContents(artifactType: string, pattern: string): Promise<string> { | ||||||
|  |         const cacheKeyPrefix = getCacheKeyPrefix() | ||||||
|  |         const key = await glob.hashFiles(pattern) | ||||||
|  | 
 | ||||||
|  |         cacheDebug(`Generating cache key for ${artifactType} from files matching: ${pattern}`) | ||||||
|  | 
 | ||||||
|  |         return `${cacheKeyPrefix}${artifactType}-${key}` | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Run actions sequentially if debugging is enabled
 | ||||||
|  |     private async awaitForDebugging(p: Promise<ExtractedCacheEntry>): Promise<ExtractedCacheEntry> { | ||||||
|  |         if (isCacheDebuggingEnabled()) { | ||||||
|  |             await p | ||||||
|  |         } | ||||||
|  |         return p | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Load information about the extracted cache entries previously restored/saved. This is loaded from the 'cache-metadata.json' file. | ||||||
|  |      */ | ||||||
|  |     protected loadExtractedCacheEntries(): ExtractedCacheEntry[] { | ||||||
|  |         const cacheMetadataFile = this.getCacheMetadataFile() | ||||||
|  |         if (!fs.existsSync(cacheMetadataFile)) { | ||||||
|  |             return [] | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const filedata = fs.readFileSync(cacheMetadataFile, 'utf-8') | ||||||
|  |         cacheDebug(`Loaded cache metadata: ${filedata}`) | ||||||
|  |         const extractedCacheEntryMetadata = JSON.parse(filedata) as ExtractedCacheEntryMetadata | ||||||
|  |         return extractedCacheEntryMetadata.entries | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Saves information about the extracted cache entries into the 'cache-metadata.json' file. | ||||||
|  |      */ | ||||||
|  |     private saveMetadataForCacheResults(results: ExtractedCacheEntry[]): void { | ||||||
|  |         const extractedCacheEntryMetadata = new ExtractedCacheEntryMetadata() | ||||||
|  |         extractedCacheEntryMetadata.entries = results.filter(x => x.cacheKey !== undefined) | ||||||
|  | 
 | ||||||
|  |         const filedata = JSON.stringify(extractedCacheEntryMetadata) | ||||||
|  |         cacheDebug(`Saving cache metadata: ${filedata}`) | ||||||
|  | 
 | ||||||
|  |         fs.writeFileSync(this.getCacheMetadataFile(), filedata, 'utf-8') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private getCacheMetadataFile(): string { | ||||||
|  |         const actionMetadataDirectory = path.resolve(this.gradleUserHome, META_FILE_DIR) | ||||||
|  |         fs.mkdirSync(actionMetadataDirectory, {recursive: true}) | ||||||
|  | 
 | ||||||
|  |         return path.resolve(actionMetadataDirectory, `${this.extractorName}-entry-metadata.json`) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected abstract getExtractedCacheEntryDefinitions(): ExtractedCacheEntryDefinition[] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class GradleHomeEntryExtractor extends AbstractEntryExtractor { | ||||||
|  |     constructor(gradleUserHome: string) { | ||||||
|  |         super(gradleUserHome, 'gradle-home') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async extract(listener: CacheListener): Promise<void> { | ||||||
|  |         await this.deleteWrapperZips() | ||||||
|  |         return super.extract(listener) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Delete any downloaded wrapper zip files that are not needed after extraction. | ||||||
|  |      * These files are cleaned up by Gradle >= 7.5, but for older versions we remove them manually. | ||||||
|  |      */ | ||||||
|  |     private async deleteWrapperZips(): Promise<void> { | ||||||
|  |         const wrapperZips = path.resolve(this.gradleUserHome, 'wrapper/dists/*/*/*.zip') | ||||||
|  |         const globber = await glob.create(wrapperZips, { | ||||||
|  |             implicitDescendants: false | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|  |         for (const wrapperZip of await globber.glob()) { | ||||||
|  |             cacheDebug(`Deleting wrapper zip: ${wrapperZip}`) | ||||||
|  |             await tryDelete(wrapperZip) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Return the extracted cache entry definitions, which determine which artifacts will be cached | ||||||
|  |      * separately from the rest of the Gradle User Home cache entry. | ||||||
|  |      */ | ||||||
|  |     protected getExtractedCacheEntryDefinitions(): ExtractedCacheEntryDefinition[] { | ||||||
|  |         const entryDefinition = ( | ||||||
|  |             artifactType: string, | ||||||
|  |             patterns: string[], | ||||||
|  |             bundle: boolean | ||||||
|  |         ): ExtractedCacheEntryDefinition => { | ||||||
|  |             const resolvedPatterns = patterns | ||||||
|  |                 .map(x => { | ||||||
|  |                     const isDir = x.endsWith('/') | ||||||
|  |                     const resolved = path.resolve(this.gradleUserHome, x) | ||||||
|  |                     return isDir ? `${resolved}/` : resolved // Restore trailing '/' removed by path.resolve()
 | ||||||
|  |                 }) | ||||||
|  |                 .join('\n') | ||||||
|  |             return new ExtractedCacheEntryDefinition(artifactType, resolvedPatterns, bundle) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return [ | ||||||
|  |             entryDefinition('generated-gradle-jars', ['caches/*/generated-gradle-jars/*.jar'], false), | ||||||
|  |             entryDefinition('wrapper-zips', ['wrapper/dists/*/*/'], false), // Entire wrapper directory cached together
 | ||||||
|  |             entryDefinition('java-toolchains', ['jdks/*.zip', 'jdks/*.tar.gz'], false), | ||||||
|  |             entryDefinition('dependencies', ['caches/modules-*/files-*/*/*/*/*'], true), | ||||||
|  |             entryDefinition('instrumented-jars', ['caches/jars-*/*'], true), | ||||||
|  |             entryDefinition('kotlin-dsl', ['caches/*/kotlin-dsl/*/*'], true) | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class ConfigurationCacheEntryExtractor extends AbstractEntryExtractor { | ||||||
|  |     constructor(gradleUserHome: string) { | ||||||
|  |         super(gradleUserHome, 'configuration-cache') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Handle the case where Gradle User Home has not been fully restored, so that the configuration-cache | ||||||
|  |      * entry is not reusable. | ||||||
|  |      */ | ||||||
|  |     async restore(listener: CacheListener): Promise<void> { | ||||||
|  |         if (listener.fullyRestored) { | ||||||
|  |             return super.restore(listener) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         core.info('Not restoring configuration-cache state, as Gradle User Home was not fully restored') | ||||||
|  |         for (const cacheEntry of this.loadExtractedCacheEntries()) { | ||||||
|  |             listener.entry(cacheEntry.pattern).markRequested('NOT_RESTORED') | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Extract cache entries for the configuration cache in each project. | ||||||
|  |      */ | ||||||
|  |     protected getExtractedCacheEntryDefinitions(): ExtractedCacheEntryDefinition[] { | ||||||
|  |         return this.getProjectRoots().map(projectRoot => { | ||||||
|  |             const configCachePath = path.resolve(projectRoot, '.gradle/configuration-cache') | ||||||
|  |             return new ExtractedCacheEntryDefinition( | ||||||
|  |                 'configuration-cache', | ||||||
|  |                 configCachePath, | ||||||
|  |                 true | ||||||
|  |             ).withNonUniqueFileNames() | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * For every Gradle invocation, we record the project root directory. This method returns the entire | ||||||
|  |      * set of project roots, to allow saving of configuration-cache entries for each. | ||||||
|  |      */ | ||||||
|  |     private getProjectRoots(): string[] { | ||||||
|  |         const buildResults = loadBuildResults() | ||||||
|  |         const projectRootDirs = buildResults.map(x => x.rootProjectDir) | ||||||
|  |         return [...new Set(projectRootDirs)] // Remove duplicates
 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										228
									
								
								src/cache-reporting.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								src/cache-reporting.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,228 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as cache from '@actions/cache' | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Collects information on what entries were saved and restored during the action. | ||||||
|  |  * This information is used to generate a summary of the cache usage. | ||||||
|  |  */ | ||||||
|  | export class CacheListener { | ||||||
|  |     cacheEntries: CacheEntryListener[] = [] | ||||||
|  |     cacheReadOnly = false | ||||||
|  |     cacheWriteOnly = false | ||||||
|  |     cacheDisabled = false | ||||||
|  | 
 | ||||||
|  |     get fullyRestored(): boolean { | ||||||
|  |         return this.cacheEntries.every(x => !x.wasRequestedButNotRestored()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     get cacheStatus(): string { | ||||||
|  |         if (!cache.isFeatureAvailable()) return 'not available' | ||||||
|  |         if (this.cacheDisabled) return 'disabled' | ||||||
|  |         if (this.cacheWriteOnly) return 'write-only' | ||||||
|  |         if (this.cacheReadOnly) return 'read-only' | ||||||
|  |         return 'enabled' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     entry(name: string): CacheEntryListener { | ||||||
|  |         for (const entry of this.cacheEntries) { | ||||||
|  |             if (entry.entryName === name) { | ||||||
|  |                 return entry | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const newEntry = new CacheEntryListener(name) | ||||||
|  |         this.cacheEntries.push(newEntry) | ||||||
|  |         return newEntry | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     stringify(): string { | ||||||
|  |         return JSON.stringify(this) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static rehydrate(stringRep: string): CacheListener { | ||||||
|  |         if (stringRep === '') { | ||||||
|  |             return new CacheListener() | ||||||
|  |         } | ||||||
|  |         const rehydrated: CacheListener = Object.assign(new CacheListener(), JSON.parse(stringRep)) | ||||||
|  |         const entries = rehydrated.cacheEntries | ||||||
|  |         for (let index = 0; index < entries.length; index++) { | ||||||
|  |             const rawEntry = entries[index] | ||||||
|  |             entries[index] = Object.assign(new CacheEntryListener(rawEntry.entryName), rawEntry) | ||||||
|  |         } | ||||||
|  |         return rehydrated | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Collects information on the state of a single cache entry. | ||||||
|  |  */ | ||||||
|  | export class CacheEntryListener { | ||||||
|  |     entryName: string | ||||||
|  |     requestedKey: string | undefined | ||||||
|  |     requestedRestoreKeys: string[] | undefined | ||||||
|  |     restoredKey: string | undefined | ||||||
|  |     restoredSize: number | undefined | ||||||
|  |     notRestored: string | undefined | ||||||
|  | 
 | ||||||
|  |     savedKey: string | undefined | ||||||
|  |     savedSize: number | undefined | ||||||
|  |     notSaved: string | undefined | ||||||
|  | 
 | ||||||
|  |     constructor(entryName: string) { | ||||||
|  |         this.entryName = entryName | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     wasRequestedButNotRestored(): boolean { | ||||||
|  |         return this.requestedKey !== undefined && this.restoredKey === undefined | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     markRequested(key: string, restoreKeys: string[] = []): CacheEntryListener { | ||||||
|  |         this.requestedKey = key | ||||||
|  |         this.requestedRestoreKeys = restoreKeys | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     markRestored(key: string, size: number | undefined): CacheEntryListener { | ||||||
|  |         this.restoredKey = key | ||||||
|  |         this.restoredSize = size | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     markNotRestored(message: string): CacheEntryListener { | ||||||
|  |         this.notRestored = message | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     markSaved(key: string, size: number | undefined): CacheEntryListener { | ||||||
|  |         this.savedKey = key | ||||||
|  |         this.savedSize = size | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     markAlreadyExists(key: string): CacheEntryListener { | ||||||
|  |         this.savedKey = key | ||||||
|  |         this.savedSize = 0 | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     markNotSaved(message: string): CacheEntryListener { | ||||||
|  |         this.notSaved = message | ||||||
|  |         return this | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function writeCachingReport(listener: CacheListener): void { | ||||||
|  |     const entries = listener.cacheEntries | ||||||
|  | 
 | ||||||
|  |     core.summary.addRaw( | ||||||
|  |         `\n<details><summary><h4>Caching for gradle-build-action was ${listener.cacheStatus} - expand for details</h4></summary>\n` | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     core.summary.addTable([ | ||||||
|  |         [ | ||||||
|  |             {data: '', header: true}, | ||||||
|  |             {data: 'Count', header: true}, | ||||||
|  |             {data: 'Total Size (Mb)', header: true} | ||||||
|  |         ], | ||||||
|  |         ['Entries Restored', `${getCount(entries, e => e.restoredSize)}`, `${getSize(entries, e => e.restoredSize)}`], | ||||||
|  |         ['Entries Saved', `${getCount(entries, e => e.savedSize)}`, `${getSize(entries, e => e.savedSize)}`] | ||||||
|  |     ]) | ||||||
|  | 
 | ||||||
|  |     core.summary.addHeading('Cache Entry Details', 5) | ||||||
|  | 
 | ||||||
|  |     const entryDetails = renderEntryDetails(listener) | ||||||
|  |     core.summary.addRaw(`<pre>
 | ||||||
|  | ${entryDetails} | ||||||
|  | </pre> | ||||||
|  | </details> | ||||||
|  | `)
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function logCachingReport(listener: CacheListener): void { | ||||||
|  |     const entries = listener.cacheEntries | ||||||
|  | 
 | ||||||
|  |     core.startGroup(`Caching for gradle-build-action was ${listener.cacheStatus} - expand for details`) | ||||||
|  | 
 | ||||||
|  |     core.info( | ||||||
|  |         `Entries Restored: ${getCount(entries, e => e.restoredSize)} (${getSize(entries, e => e.restoredSize)} Mb)` | ||||||
|  |     ) | ||||||
|  |     core.info(`Entries Saved   : ${getCount(entries, e => e.savedSize)} (${getSize(entries, e => e.savedSize)} Mb)`) | ||||||
|  | 
 | ||||||
|  |     core.info(`Cache Entry Details`) | ||||||
|  |     core.info(renderEntryDetails(listener)) | ||||||
|  | 
 | ||||||
|  |     core.endGroup() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function renderEntryDetails(listener: CacheListener): string { | ||||||
|  |     return listener.cacheEntries | ||||||
|  |         .map( | ||||||
|  |             entry => `Entry: ${entry.entryName} | ||||||
|  |     Requested Key : ${entry.requestedKey ?? ''} | ||||||
|  |     Restored  Key : ${entry.restoredKey ?? ''} | ||||||
|  |               Size: ${formatSize(entry.restoredSize)} | ||||||
|  |               ${getRestoredMessage(entry, listener.cacheWriteOnly)} | ||||||
|  |     Saved     Key : ${entry.savedKey ?? ''} | ||||||
|  |               Size: ${formatSize(entry.savedSize)} | ||||||
|  |               ${getSavedMessage(entry, listener.cacheReadOnly)} | ||||||
|  | ` | ||||||
|  |         ) | ||||||
|  |         .join('---\n') | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getRestoredMessage(entry: CacheEntryListener, cacheWriteOnly: boolean): string { | ||||||
|  |     if (entry.notRestored) { | ||||||
|  |         return `(Entry not restored: ${entry.notRestored})` | ||||||
|  |     } | ||||||
|  |     if (cacheWriteOnly) { | ||||||
|  |         return '(Entry not restored: cache is write-only)' | ||||||
|  |     } | ||||||
|  |     if (entry.requestedKey === undefined) { | ||||||
|  |         return '(Entry not restored: not requested)' | ||||||
|  |     } | ||||||
|  |     if (entry.restoredKey === undefined) { | ||||||
|  |         return '(Entry not restored: no match found)' | ||||||
|  |     } | ||||||
|  |     if (entry.restoredKey === entry.requestedKey) { | ||||||
|  |         return '(Entry restored: exact match found)' | ||||||
|  |     } | ||||||
|  |     return '(Entry restored: partial match found)' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getSavedMessage(entry: CacheEntryListener, cacheReadOnly: boolean): string { | ||||||
|  |     if (entry.notSaved) { | ||||||
|  |         return `(Entry not saved: ${entry.notSaved})` | ||||||
|  |     } | ||||||
|  |     if (entry.savedKey === undefined) { | ||||||
|  |         if (cacheReadOnly) { | ||||||
|  |             return '(Entry not saved: cache is read-only)' | ||||||
|  |         } | ||||||
|  |         return '(Entry not saved: reason unknown)' | ||||||
|  |     } | ||||||
|  |     if (entry.savedSize === 0) { | ||||||
|  |         return '(Entry not saved: entry with key already exists)' | ||||||
|  |     } | ||||||
|  |     return '(Entry saved)' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getCount( | ||||||
|  |     cacheEntries: CacheEntryListener[], | ||||||
|  |     predicate: (value: CacheEntryListener) => number | undefined | ||||||
|  | ): number { | ||||||
|  |     return cacheEntries.filter(e => predicate(e)).length | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getSize( | ||||||
|  |     cacheEntries: CacheEntryListener[], | ||||||
|  |     predicate: (value: CacheEntryListener) => number | undefined | ||||||
|  | ): number { | ||||||
|  |     const bytes = cacheEntries.map(e => predicate(e) ?? 0).reduce((p, v) => p + v, 0) | ||||||
|  |     return Math.round(bytes / (1024 * 1024)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function formatSize(bytes: number | undefined): string { | ||||||
|  |     if (bytes === undefined || bytes === 0) { | ||||||
|  |         return '' | ||||||
|  |     } | ||||||
|  |     return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)` | ||||||
|  | } | ||||||
							
								
								
									
										252
									
								
								src/cache-utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								src/cache-utils.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,252 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as cache from '@actions/cache' | ||||||
|  | import * as github from '@actions/github' | ||||||
|  | import * as exec from '@actions/exec' | ||||||
|  | 
 | ||||||
|  | import * as crypto from 'crypto' | ||||||
|  | import * as path from 'path' | ||||||
|  | import * as fs from 'fs' | ||||||
|  | 
 | ||||||
|  | import {CacheEntryListener} from './cache-reporting' | ||||||
|  | 
 | ||||||
|  | const CACHE_PROTOCOL_VERSION = 'v6-' | ||||||
|  | 
 | ||||||
|  | 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' | ||||||
|  | const CACHE_KEY_JOB_INSTANCE_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB_INSTANCE' | ||||||
|  | const CACHE_KEY_JOB_EXECUTION_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION' | ||||||
|  | 
 | ||||||
|  | const SEGMENT_DOWNLOAD_TIMEOUT_VAR = 'SEGMENT_DOWNLOAD_TIMEOUT_MINS' | ||||||
|  | const SEGMENT_DOWNLOAD_TIMEOUT_DEFAULT = 10 * 60 * 1000 // 10 minutes
 | ||||||
|  | 
 | ||||||
|  | export function isCacheDisabled(): boolean { | ||||||
|  |     if (!cache.isFeatureAvailable()) { | ||||||
|  |         return true | ||||||
|  |     } | ||||||
|  |     return core.getBooleanInput(CACHE_DISABLED_PARAMETER) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function isCacheReadOnly(): boolean { | ||||||
|  |     return !isCacheWriteOnly() && core.getBooleanInput(CACHE_READONLY_PARAMETER) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function isCacheWriteOnly(): boolean { | ||||||
|  |     return core.getBooleanInput(CACHE_WRITEONLY_PARAMETER) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function isCacheDebuggingEnabled(): boolean { | ||||||
|  |     return process.env[CACHE_DEBUG_VAR] ? true : false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function isCacheCleanupEnabled(): boolean { | ||||||
|  |     return core.getBooleanInput(CACHE_CLEANUP_ENABLED_PARAMETER) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Represents a key used to restore a cache entry. | ||||||
|  |  * The Github Actions cache will first try for an exact match on the key. | ||||||
|  |  * If that fails, it will try for a prefix match on any of the restoreKeys. | ||||||
|  |  */ | ||||||
|  | export class CacheKey { | ||||||
|  |     key: string | ||||||
|  |     restoreKeys: string[] | ||||||
|  | 
 | ||||||
|  |     constructor(key: string, restoreKeys: string[]) { | ||||||
|  |         this.key = key | ||||||
|  |         this.restoreKeys = restoreKeys | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Generates a cache key specific to the current job execution. | ||||||
|  |  * The key is constructed from the following inputs (with some user overrides): | ||||||
|  |  * - The cache protocol version | ||||||
|  |  * - The name of the cache | ||||||
|  |  * - The runner operating system | ||||||
|  |  * - The name of the Job being executed | ||||||
|  |  * - The matrix values for the Job being executed (job context) | ||||||
|  |  * - The SHA of the commit being executed | ||||||
|  |  * | ||||||
|  |  * Caches are restored by trying to match the these key prefixes in order: | ||||||
|  |  * - The full key with SHA | ||||||
|  |  * - A previous key for this Job + matrix | ||||||
|  |  * - Any previous key for this Job (any matrix) | ||||||
|  |  * - Any previous key for this cache on the current OS | ||||||
|  |  */ | ||||||
|  | export function generateCacheKey(cacheName: string): CacheKey { | ||||||
|  |     const cacheKeyBase = `${getCacheKeyPrefix()}${CACHE_PROTOCOL_VERSION}${cacheName}` | ||||||
|  | 
 | ||||||
|  |     // At the most general level, share caches for all executions on the same OS
 | ||||||
|  |     const cacheKeyForEnvironment = `${cacheKeyBase}|${getCacheKeyEnvironment()}` | ||||||
|  | 
 | ||||||
|  |     // Prefer caches that run this job
 | ||||||
|  |     const cacheKeyForJob = `${cacheKeyForEnvironment}|${getCacheKeyJob()}` | ||||||
|  | 
 | ||||||
|  |     // Prefer (even more) jobs that run this job with the same context (matrix)
 | ||||||
|  |     const cacheKeyForJobContext = `${cacheKeyForJob}[${getCacheKeyJobInstance()}]` | ||||||
|  | 
 | ||||||
|  |     // Exact match on Git SHA
 | ||||||
|  |     const cacheKey = `${cacheKeyForJobContext}-${getCacheKeyJobExecution()}` | ||||||
|  | 
 | ||||||
|  |     if (core.getBooleanInput(STRICT_CACHE_MATCH_PARAMETER)) { | ||||||
|  |         return new CacheKey(cacheKey, [cacheKeyForJobContext]) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return new CacheKey(cacheKey, [cacheKeyForJobContext, cacheKeyForJob, cacheKeyForEnvironment]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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_VAR] || '' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getCacheKeyEnvironment(): string { | ||||||
|  |     const runnerOs = process.env['RUNNER_OS'] || '' | ||||||
|  |     return process.env[CACHE_KEY_OS_VAR] || runnerOs | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getCacheKeyJob(): string { | ||||||
|  |     // Prefix can be used to force change all cache keys (defaults to cache protocol version)
 | ||||||
|  |     return process.env[CACHE_KEY_JOB_VAR] || github.context.job | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getCacheKeyJobInstance(): string { | ||||||
|  |     const override = process.env[CACHE_KEY_JOB_INSTANCE_VAR] | ||||||
|  |     if (override) { | ||||||
|  |         return override | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 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) | ||||||
|  |     return hashStrings([workflowJobContext]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getCacheKeyJobExecution(): string { | ||||||
|  |     // Used to associate a cache key with a particular execution (default is bound to the git commit sha)
 | ||||||
|  |     return process.env[CACHE_KEY_JOB_EXECUTION_VAR] || github.context.sha | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function hashFileNames(fileNames: string[]): string { | ||||||
|  |     return hashStrings(fileNames.map(x => x.replace(new RegExp(`\\${path.sep}`, 'g'), '/'))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function hashStrings(values: string[]): string { | ||||||
|  |     const hash = crypto.createHash('md5') | ||||||
|  |     for (const value of values) { | ||||||
|  |         hash.update(value) | ||||||
|  |     } | ||||||
|  |     return hash.digest('hex') | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function restoreCache( | ||||||
|  |     cachePath: string[], | ||||||
|  |     cacheKey: string, | ||||||
|  |     cacheRestoreKeys: string[], | ||||||
|  |     listener: CacheEntryListener | ||||||
|  | ): Promise<cache.CacheEntry | undefined> { | ||||||
|  |     listener.markRequested(cacheKey, cacheRestoreKeys) | ||||||
|  |     try { | ||||||
|  |         // Only override the read timeout if the SEGMENT_DOWNLOAD_TIMEOUT_MINS env var has NOT been set
 | ||||||
|  |         const cacheRestoreOptions = process.env[SEGMENT_DOWNLOAD_TIMEOUT_VAR] | ||||||
|  |             ? {} | ||||||
|  |             : {segmentTimeoutInMs: SEGMENT_DOWNLOAD_TIMEOUT_DEFAULT} | ||||||
|  |         const restoredEntry = await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys, cacheRestoreOptions) | ||||||
|  |         if (restoredEntry !== undefined) { | ||||||
|  |             listener.markRestored(restoredEntry.key, restoredEntry.size) | ||||||
|  |         } | ||||||
|  |         return restoredEntry | ||||||
|  |     } catch (error) { | ||||||
|  |         listener.markNotRestored((error as Error).message) | ||||||
|  |         handleCacheFailure(error, `Failed to restore ${cacheKey}`) | ||||||
|  |         return undefined | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function saveCache(cachePath: string[], cacheKey: string, listener: CacheEntryListener): Promise<void> { | ||||||
|  |     try { | ||||||
|  |         const savedEntry = await cache.saveCache(cachePath, cacheKey) | ||||||
|  |         listener.markSaved(savedEntry.key, savedEntry.size) | ||||||
|  |     } catch (error) { | ||||||
|  |         if (error instanceof cache.ReserveCacheError) { | ||||||
|  |             listener.markAlreadyExists(cacheKey) | ||||||
|  |         } else { | ||||||
|  |             listener.markNotSaved((error as Error).message) | ||||||
|  |         } | ||||||
|  |         handleCacheFailure(error, `Failed to save cache entry with path '${cachePath}' and key: ${cacheKey}`) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function cacheDebug(message: string): void { | ||||||
|  |     if (isCacheDebuggingEnabled()) { | ||||||
|  |         core.info(message) | ||||||
|  |     } else { | ||||||
|  |         core.debug(message) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function handleCacheFailure(error: unknown, message: string): void { | ||||||
|  |     if (error instanceof cache.ValidationError) { | ||||||
|  |         // Fail on cache validation errors
 | ||||||
|  |         throw error | ||||||
|  |     } | ||||||
|  |     if (error instanceof cache.ReserveCacheError) { | ||||||
|  |         // Reserve cache errors are expected if the artifact has been previously cached
 | ||||||
|  |         core.info(`${message}: ${error}`) | ||||||
|  |     } else { | ||||||
|  |         // Warn on all other errors
 | ||||||
|  |         core.warning(`${message}: ${error}`) | ||||||
|  |         if (error instanceof Error && error.stack) { | ||||||
|  |             cacheDebug(error.stack) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Attempt to delete a file or directory, waiting to allow locks to be released | ||||||
|  |  */ | ||||||
|  | export async function tryDelete(file: string): Promise<void> { | ||||||
|  |     const maxAttempts = 5 | ||||||
|  |     for (let attempt = 1; attempt <= maxAttempts; attempt++) { | ||||||
|  |         if (!fs.existsSync(file)) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |         try { | ||||||
|  |             const stat = fs.lstatSync(file) | ||||||
|  |             if (stat.isDirectory()) { | ||||||
|  |                 fs.rmdirSync(file, {recursive: true}) | ||||||
|  |             } else { | ||||||
|  |                 fs.unlinkSync(file) | ||||||
|  |             } | ||||||
|  |             return | ||||||
|  |         } catch (error) { | ||||||
|  |             if (attempt === maxAttempts) { | ||||||
|  |                 core.warning(`Failed to delete ${file}, which will impact caching. 
 | ||||||
|  | It is likely locked by another process. Output of 'jps -ml': | ||||||
|  | ${await getJavaProcesses()}`)
 | ||||||
|  |                 throw error | ||||||
|  |             } else { | ||||||
|  |                 cacheDebug(`Attempt to delete ${file} failed. Will try again.`) | ||||||
|  |                 await delay(1000) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function delay(ms: number): Promise<void> { | ||||||
|  |     return new Promise(resolve => setTimeout(resolve, ms)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function getJavaProcesses(): Promise<string> { | ||||||
|  |     const jpsOutput = await exec.getExecOutput('jps', ['-lm']) | ||||||
|  |     return jpsOutput.stdout | ||||||
|  | } | ||||||
							
								
								
									
										88
									
								
								src/caches.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/caches.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import {isCacheCleanupEnabled, isCacheDisabled, isCacheReadOnly, isCacheWriteOnly} from './cache-utils' | ||||||
|  | import {CacheListener} from './cache-reporting' | ||||||
|  | import {DaemonController} from './daemon-controller' | ||||||
|  | import {GradleStateCache} from './cache-base' | ||||||
|  | import {CacheCleaner} from './cache-cleaner' | ||||||
|  | 
 | ||||||
|  | const CACHE_RESTORED_VAR = 'GRADLE_BUILD_ACTION_CACHE_RESTORED' | ||||||
|  | 
 | ||||||
|  | export async function restore(gradleUserHome: string, cacheListener: CacheListener): Promise<void> { | ||||||
|  |     // Bypass restore cache on all but first action step in workflow.
 | ||||||
|  |     if (process.env[CACHE_RESTORED_VAR]) { | ||||||
|  |         core.info('Cache only restored on first action step.') | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  |     core.exportVariable(CACHE_RESTORED_VAR, true) | ||||||
|  | 
 | ||||||
|  |     const gradleStateCache = new GradleStateCache(gradleUserHome) | ||||||
|  | 
 | ||||||
|  |     if (isCacheDisabled()) { | ||||||
|  |         core.info('Cache is disabled: will not restore state from previous builds.') | ||||||
|  |         // Initialize the Gradle User Home even when caching is disabled.
 | ||||||
|  |         gradleStateCache.init() | ||||||
|  |         cacheListener.cacheDisabled = true | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (gradleStateCache.cacheOutputExists()) { | ||||||
|  |         core.info('Gradle User Home already exists: will not restore from cache.') | ||||||
|  |         // Initialize pre-existing Gradle User Home.
 | ||||||
|  |         gradleStateCache.init() | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     gradleStateCache.init() | ||||||
|  |     // Mark the state as restored so that post-action will perform save.
 | ||||||
|  |     core.saveState(CACHE_RESTORED_VAR, true) | ||||||
|  | 
 | ||||||
|  |     if (isCacheWriteOnly()) { | ||||||
|  |         core.info('Cache is write-only: will not restore from cache.') | ||||||
|  |         cacheListener.cacheWriteOnly = true | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await core.group('Restore Gradle state from cache', async () => { | ||||||
|  |         await gradleStateCache.restore(cacheListener) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     if (isCacheCleanupEnabled() && !isCacheReadOnly()) { | ||||||
|  |         core.info('Preparing cache for cleanup.') | ||||||
|  |         const cacheCleaner = new CacheCleaner(gradleUserHome, process.env['RUNNER_TEMP']!) | ||||||
|  |         await cacheCleaner.prepare() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function save( | ||||||
|  |     gradleUserHome: string, | ||||||
|  |     cacheListener: CacheListener, | ||||||
|  |     daemonController: DaemonController | ||||||
|  | ): Promise<void> { | ||||||
|  |     if (isCacheDisabled()) { | ||||||
|  |         core.info('Cache is disabled: will not save state for later builds.') | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!core.getState(CACHE_RESTORED_VAR)) { | ||||||
|  |         core.info('Cache will not be saved: not restored in main action step.') | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (isCacheReadOnly()) { | ||||||
|  |         core.info('Cache is read-only: will not save state for use in subsequent builds.') | ||||||
|  |         cacheListener.cacheReadOnly = true | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await daemonController.stopAllDaemons() | ||||||
|  | 
 | ||||||
|  |     if (isCacheCleanupEnabled()) { | ||||||
|  |         core.info('Forcing cache cleanup.') | ||||||
|  |         const cacheCleaner = new CacheCleaner(gradleUserHome, process.env['RUNNER_TEMP']!) | ||||||
|  |         await cacheCleaner.forceCleanup() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await core.group('Caching Gradle state', async () => { | ||||||
|  |         return new GradleStateCache(gradleUserHome).save(cacheListener) | ||||||
|  |     }) | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								src/daemon-controller.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/daemon-controller.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as exec from '@actions/exec' | ||||||
|  | import * as fs from 'fs' | ||||||
|  | import * as path from 'path' | ||||||
|  | import {BuildResult} from './build-results' | ||||||
|  | 
 | ||||||
|  | export class DaemonController { | ||||||
|  |     private readonly gradleHomes | ||||||
|  | 
 | ||||||
|  |     constructor(buildResults: BuildResult[]) { | ||||||
|  |         const allHomes = buildResults.map(buildResult => buildResult.gradleHomeDir) | ||||||
|  |         this.gradleHomes = Array.from(new Set(allHomes)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async stopAllDaemons(): Promise<void> { | ||||||
|  |         core.info('Stopping all Gradle daemons before saving Gradle User Home state') | ||||||
|  | 
 | ||||||
|  |         const executions: Promise<number>[] = [] | ||||||
|  |         const args = ['--stop'] | ||||||
|  | 
 | ||||||
|  |         for (const gradleHome of this.gradleHomes) { | ||||||
|  |             const executable = path.resolve(gradleHome, 'bin', 'gradle') | ||||||
|  |             if (!fs.existsSync(executable)) { | ||||||
|  |                 core.warning(`Gradle executable not found at ${executable}. Could not stop Gradle daemons.`) | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             core.info(`Stopping Gradle daemons for ${gradleHome}`) | ||||||
|  |             executions.push( | ||||||
|  |                 exec.exec(executable, args, { | ||||||
|  |                     ignoreReturnCode: true | ||||||
|  |                 }) | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  |         await Promise.all(executions) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								src/execution.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/execution.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as exec from '@actions/exec' | ||||||
|  | import fs from 'fs' | ||||||
|  | import * as gradlew from './gradlew' | ||||||
|  | 
 | ||||||
|  | export async function executeGradleBuild(executable: string | undefined, root: string, args: string[]): Promise<void> { | ||||||
|  |     // Use the provided executable, or look for a Gradle wrapper script to run
 | ||||||
|  |     const toExecute = executable ?? gradlew.locateGradleWrapperScript(root) | ||||||
|  |     verifyIsExecutableScript(toExecute) | ||||||
|  |     const status: number = await exec.exec(toExecute, args, { | ||||||
|  |         cwd: root, | ||||||
|  |         ignoreReturnCode: true | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     if (status !== 0) { | ||||||
|  |         core.setFailed(`Gradle build failed: see console output for details`) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function verifyIsExecutableScript(toExecute: string): void { | ||||||
|  |     try { | ||||||
|  |         fs.accessSync(toExecute, fs.constants.X_OK) | ||||||
|  |     } catch (err) { | ||||||
|  |         throw new Error(`Gradle script '${toExecute}' is not executable.`) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								src/gradlew.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/gradlew.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | import * as path from 'path' | ||||||
|  | import fs from 'fs' | ||||||
|  | 
 | ||||||
|  | const IS_WINDOWS = process.platform === 'win32' | ||||||
|  | 
 | ||||||
|  | export function wrapperScriptFilename(): string { | ||||||
|  |     return IS_WINDOWS ? 'gradlew.bat' : 'gradlew' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function installScriptFilename(): string { | ||||||
|  |     return IS_WINDOWS ? 'gradle.bat' : 'gradle' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function locateGradleWrapperScript(buildRootDirectory: string): string { | ||||||
|  |     validateGradleWrapper(buildRootDirectory) | ||||||
|  |     return path.resolve(buildRootDirectory, wrapperScriptFilename()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function validateGradleWrapper(buildRootDirectory: string): void { | ||||||
|  |     const wrapperProperties = path.resolve(buildRootDirectory, 'gradle/wrapper/gradle-wrapper.properties') | ||||||
|  |     if (!fs.existsSync(wrapperProperties)) { | ||||||
|  |         throw new Error( | ||||||
|  |             `Cannot locate a Gradle wrapper properties file at '${wrapperProperties}'. Specify 'gradle-version' or 'gradle-executable' for projects without Gradle wrapper configured.` | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										94
									
								
								src/job-summary.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/job-summary.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import {BuildResult} from './build-results' | ||||||
|  | import {writeCachingReport, CacheListener, logCachingReport} from './cache-reporting' | ||||||
|  | 
 | ||||||
|  | export async function writeJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> { | ||||||
|  |     core.info('Writing job summary') | ||||||
|  | 
 | ||||||
|  |     if (buildResults.length === 0) { | ||||||
|  |         core.debug('No Gradle build results found. Summary table will not be generated.') | ||||||
|  |     } else { | ||||||
|  |         writeSummaryTable(buildResults) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     writeCachingReport(cacheListener) | ||||||
|  | 
 | ||||||
|  |     await core.summary.write() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function logJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> { | ||||||
|  |     if (buildResults.length === 0) { | ||||||
|  |         core.debug('No Gradle build results found. Summary table will not be logged.') | ||||||
|  |     } else { | ||||||
|  |         logSummaryTable(buildResults) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     logCachingReport(cacheListener) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function writeSummaryTable(results: BuildResult[]): void { | ||||||
|  |     core.summary.addHeading('Gradle Builds', 3) | ||||||
|  | 
 | ||||||
|  |     core.summary.addRaw(` | ||||||
|  | <table> | ||||||
|  |     <tr> | ||||||
|  |         <th>Root Project</th> | ||||||
|  |         <th>Requested Tasks</th> | ||||||
|  |         <th>Gradle Version</th> | ||||||
|  |         <th>Build Outcome</th> | ||||||
|  |         <th>Build Scan™</th> | ||||||
|  |     </tr>${results.map(result => renderBuildResultRow(result)).join('')} | ||||||
|  | </table> | ||||||
|  |     `)
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function renderBuildResultRow(result: BuildResult): string { | ||||||
|  |     return ` | ||||||
|  |     <tr> | ||||||
|  |         <td>${result.rootProjectName}</td> | ||||||
|  |         <td>${result.requestedTasks}</td> | ||||||
|  |         <td align='center'>${result.gradleVersion}</td> | ||||||
|  |         <td align='center'>${renderOutcome(result)}</td> | ||||||
|  |         <td>${renderBuildScan(result)}</td> | ||||||
|  |     </tr>` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function renderOutcome(result: BuildResult): string { | ||||||
|  |     return result.buildFailed ? ':x:' : ':white_check_mark:' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function renderBuildScan(result: BuildResult): string { | ||||||
|  |     if (result.buildScanFailed) { | ||||||
|  |         return renderBuildScanBadge( | ||||||
|  |             'PUBLISH_FAILED', | ||||||
|  |             'orange', | ||||||
|  |             'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting' | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |     if (result.buildScanUri) { | ||||||
|  |         return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri) | ||||||
|  |     } | ||||||
|  |     return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com') | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string { | ||||||
|  |     const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle` | ||||||
|  |     const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />` | ||||||
|  |     return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function logSummaryTable(results: BuildResult[]): void { | ||||||
|  |     core.info('============================') | ||||||
|  |     core.info('Gradle Builds') | ||||||
|  |     core.info('----------------------------') | ||||||
|  |     core.info('Root Project | Requested Tasks | Gradle Version | Build Outcome | Build Scan™') | ||||||
|  |     core.info('----------------------------') | ||||||
|  |     for (const result of results) { | ||||||
|  |         core.info( | ||||||
|  |             `${result.rootProjectName} | ${result.requestedTasks} | ${result.gradleVersion} | ${ | ||||||
|  |                 result.buildFailed ? 'FAILED' : 'SUCCESS' | ||||||
|  |             } | ${result.buildScanFailed ? 'Publish failed' : result.buildScanUri}` | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |     core.info('============================') | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								src/main.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/main.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as path from 'path' | ||||||
|  | import {parseArgsStringToArgv} from 'string-argv' | ||||||
|  | 
 | ||||||
|  | import * as setupGradle from './setup-gradle' | ||||||
|  | import * as execution from './execution' | ||||||
|  | import * as provision from './provision' | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * The main entry point for the action, called by Github Actions for the step. | ||||||
|  |  */ | ||||||
|  | export async function run(): Promise<void> { | ||||||
|  |     try { | ||||||
|  |         const workspaceDirectory = process.env[`GITHUB_WORKSPACE`] || '' | ||||||
|  |         const buildRootDirectory = resolveBuildRootDirectory(workspaceDirectory) | ||||||
|  | 
 | ||||||
|  |         await setupGradle.setup(buildRootDirectory) | ||||||
|  | 
 | ||||||
|  |         const executable = await provisionGradle(workspaceDirectory) | ||||||
|  |         // executable will be undefined if using Gradle wrapper
 | ||||||
|  |         if (executable !== undefined) { | ||||||
|  |             core.addPath(path.dirname(executable)) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Only execute if arguments have been provided
 | ||||||
|  |         const args: string[] = parseCommandLineArguments() | ||||||
|  |         if (args.length > 0) { | ||||||
|  |             await execution.executeGradleBuild(executable, buildRootDirectory, args) | ||||||
|  |         } | ||||||
|  |     } catch (error) { | ||||||
|  |         core.setFailed(String(error)) | ||||||
|  |         if (error instanceof Error && error.stack) { | ||||||
|  |             core.info(error.stack) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | run() | ||||||
|  | 
 | ||||||
|  | async function provisionGradle(workspaceDirectory: string): Promise<string | undefined> { | ||||||
|  |     const gradleVersion = core.getInput('gradle-version') | ||||||
|  |     if (gradleVersion !== '' && gradleVersion !== 'wrapper') { | ||||||
|  |         return path.resolve(await provision.gradleVersion(gradleVersion)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const gradleExecutable = core.getInput('gradle-executable') | ||||||
|  |     if (gradleExecutable !== '') { | ||||||
|  |         return path.resolve(workspaceDirectory, gradleExecutable) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return undefined | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function resolveBuildRootDirectory(baseDirectory: string): string { | ||||||
|  |     const buildRootDirectory = core.getInput('build-root-directory') | ||||||
|  |     const resolvedBuildRootDirectory = | ||||||
|  |         buildRootDirectory === '' ? path.resolve(baseDirectory) : path.resolve(baseDirectory, buildRootDirectory) | ||||||
|  |     return resolvedBuildRootDirectory | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function parseCommandLineArguments(): string[] { | ||||||
|  |     const input = core.getInput('arguments') | ||||||
|  |     return parseArgsStringToArgv(input) | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								src/post.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/post.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | 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
 | ||||||
|  | // throw an uncaught exception.  Instead of failing this action, just warn.
 | ||||||
|  | process.on('uncaughtException', e => handleFailure(e)) | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * The post-execution entry point for the action, called by Github Actions after completing all steps for the Job. | ||||||
|  |  */ | ||||||
|  | export async function run(): Promise<void> { | ||||||
|  |     try { | ||||||
|  |         await setupGradle.complete() | ||||||
|  |     } catch (error) { | ||||||
|  |         handleFailure(error) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function handleFailure(error: unknown): void { | ||||||
|  |     core.warning(`Unhandled error in Gradle post-action - job will continue: ${error}`) | ||||||
|  |     if (error instanceof Error && error.stack) { | ||||||
|  |         core.info(error.stack) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | run() | ||||||
							
								
								
									
										161
									
								
								src/provision.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/provision.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,161 @@ | |||||||
|  | import * as fs from 'fs' | ||||||
|  | import * as os from 'os' | ||||||
|  | import * as path from 'path' | ||||||
|  | import * as httpm from '@actions/http-client' | ||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as cache from '@actions/cache' | ||||||
|  | import * as toolCache from '@actions/tool-cache' | ||||||
|  | 
 | ||||||
|  | import * as gradlew from './gradlew' | ||||||
|  | import {handleCacheFailure, isCacheDisabled, isCacheReadOnly} from './cache-utils' | ||||||
|  | 
 | ||||||
|  | const gradleVersionsBaseUrl = 'https://services.gradle.org/versions' | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @return Gradle executable path | ||||||
|  |  */ | ||||||
|  | export async function gradleVersion(version: string): Promise<string> { | ||||||
|  |     switch (version) { | ||||||
|  |         case 'current': | ||||||
|  |             return gradleCurrent() | ||||||
|  |         case 'rc': | ||||||
|  |             core.warning(`Specifying gradle-version 'rc' has been deprecated. Use 'release-candidate' instead.`) | ||||||
|  |             return gradleReleaseCandidate() | ||||||
|  |         case 'release-candidate': | ||||||
|  |             return gradleReleaseCandidate() | ||||||
|  |         case 'nightly': | ||||||
|  |             return gradleNightly() | ||||||
|  |         case 'release-nightly': | ||||||
|  |             return gradleReleaseNightly() | ||||||
|  |         default: | ||||||
|  |             return gradle(version) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function gradleCurrent(): Promise<string> { | ||||||
|  |     const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/current`) | ||||||
|  |     return provisionGradle(versionInfo) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function gradleReleaseCandidate(): Promise<string> { | ||||||
|  |     const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-candidate`) | ||||||
|  |     if (versionInfo && versionInfo.version && versionInfo.downloadUrl) { | ||||||
|  |         return provisionGradle(versionInfo) | ||||||
|  |     } | ||||||
|  |     core.info('No current release-candidate found, will fallback to current') | ||||||
|  |     return gradleCurrent() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function gradleNightly(): Promise<string> { | ||||||
|  |     const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/nightly`) | ||||||
|  |     return provisionGradle(versionInfo) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function gradleReleaseNightly(): Promise<string> { | ||||||
|  |     const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-nightly`) | ||||||
|  |     return provisionGradle(versionInfo) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function gradle(version: string): Promise<string> { | ||||||
|  |     const versionInfo = await findGradleVersionDeclaration(version) | ||||||
|  |     if (!versionInfo) { | ||||||
|  |         throw new Error(`Gradle version ${version} does not exists`) | ||||||
|  |     } | ||||||
|  |     return provisionGradle(versionInfo) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function gradleVersionDeclaration(url: string): Promise<GradleVersionInfo> { | ||||||
|  |     return await httpGetGradleVersion(url) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function findGradleVersionDeclaration(version: string): Promise<GradleVersionInfo | undefined> { | ||||||
|  |     const gradleVersions = await httpGetGradleVersions(`${gradleVersionsBaseUrl}/all`) | ||||||
|  |     return gradleVersions.find((entry: GradleVersionInfo) => { | ||||||
|  |         return entry.version === version | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function provisionGradle(versionInfo: GradleVersionInfo): Promise<string> { | ||||||
|  |     return core.group(`Provision Gradle ${versionInfo.version}`, async () => { | ||||||
|  |         return locateGradleAndDownloadIfRequired(versionInfo) | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function locateGradleAndDownloadIfRequired(versionInfo: GradleVersionInfo): Promise<string> { | ||||||
|  |     const installsDir = path.join(os.homedir(), 'gradle-installations/installs') | ||||||
|  |     const installDir = path.join(installsDir, `gradle-${versionInfo.version}`) | ||||||
|  |     if (fs.existsSync(installDir)) { | ||||||
|  |         core.info(`Gradle installation already exists at ${installDir}`) | ||||||
|  |         return executableFrom(installDir) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const downloadPath = await downloadAndCacheGradleDistribution(versionInfo) | ||||||
|  |     await toolCache.extractZip(downloadPath, installsDir) | ||||||
|  |     core.info(`Extracted Gradle ${versionInfo.version} to ${installDir}`) | ||||||
|  | 
 | ||||||
|  |     const executable = executableFrom(installDir) | ||||||
|  |     fs.chmodSync(executable, '755') | ||||||
|  |     core.info(`Provisioned Gradle executable ${executable}`) | ||||||
|  | 
 | ||||||
|  |     return executable | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function downloadAndCacheGradleDistribution(versionInfo: GradleVersionInfo): Promise<string> { | ||||||
|  |     const downloadPath = path.join(os.homedir(), `gradle-installations/downloads/gradle-${versionInfo.version}-bin.zip`) | ||||||
|  | 
 | ||||||
|  |     if (isCacheDisabled()) { | ||||||
|  |         await downloadGradleDistribution(versionInfo, downloadPath) | ||||||
|  |         return downloadPath | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const cacheKey = `gradle-${versionInfo.version}` | ||||||
|  |     try { | ||||||
|  |         const restoreKey = await cache.restoreCache([downloadPath], cacheKey) | ||||||
|  |         if (restoreKey) { | ||||||
|  |             core.info(`Restored Gradle distribution ${cacheKey} from cache to ${downloadPath}`) | ||||||
|  |             return downloadPath | ||||||
|  |         } | ||||||
|  |     } catch (error) { | ||||||
|  |         handleCacheFailure(error, `Restore Gradle distribution ${versionInfo.version} failed`) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     core.info(`Gradle distribution ${versionInfo.version} not found in cache. Will download.`) | ||||||
|  |     await downloadGradleDistribution(versionInfo, downloadPath) | ||||||
|  | 
 | ||||||
|  |     if (!isCacheReadOnly()) { | ||||||
|  |         try { | ||||||
|  |             await cache.saveCache([downloadPath], cacheKey) | ||||||
|  |         } catch (error) { | ||||||
|  |             handleCacheFailure(error, `Save Gradle distribution ${versionInfo.version} failed`) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return downloadPath | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function downloadGradleDistribution(versionInfo: GradleVersionInfo, downloadPath: string): Promise<void> { | ||||||
|  |     await toolCache.downloadTool(versionInfo.downloadUrl, downloadPath) | ||||||
|  |     core.info(`Downloaded ${versionInfo.downloadUrl} to ${downloadPath} (size ${fs.statSync(downloadPath).size})`) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function executableFrom(installDir: string): string { | ||||||
|  |     return path.join(installDir, 'bin', `${gradlew.installScriptFilename()}`) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function httpGetGradleVersion(url: string): Promise<GradleVersionInfo> { | ||||||
|  |     return JSON.parse(await httpGetString(url)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function httpGetGradleVersions(url: string): Promise<GradleVersionInfo[]> { | ||||||
|  |     return JSON.parse(await httpGetString(url)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function httpGetString(url: string): Promise<string> { | ||||||
|  |     const httpClient = new httpm.HttpClient('gradle/gradle-build-action') | ||||||
|  |     const response = await httpClient.get(url) | ||||||
|  |     return response.readBody() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface GradleVersionInfo { | ||||||
|  |     version: string | ||||||
|  |     downloadUrl: string | ||||||
|  | } | ||||||
| @ -0,0 +1,59 @@ | |||||||
|  | import org.gradle.tooling.events.* | ||||||
|  | import org.gradle.tooling.events.task.* | ||||||
|  | import org.gradle.util.GradleVersion | ||||||
|  | 
 | ||||||
|  | // Can't use settingsEvaluated since this script is applied inside a settingsEvaluated handler | ||||||
|  | // But projectsEvaluated is good enough, since the build service won't catch configuration failures anyway | ||||||
|  | projectsEvaluated { | ||||||
|  |     def projectTracker = gradle.sharedServices.registerIfAbsent("gradle-build-action-buildResultsRecorder", BuildResultsRecorder, { spec -> | ||||||
|  |         spec.getParameters().getRootProjectName().set(gradle.rootProject.name) | ||||||
|  |         spec.getParameters().getRootProjectDir().set(gradle.rootProject.rootDir.absolutePath) | ||||||
|  |         spec.getParameters().getRequestedTasks().set(gradle.startParameter.taskNames.join(" ")) | ||||||
|  |         spec.getParameters().getGradleHomeDir().set(gradle.gradleHomeDir.absolutePath) | ||||||
|  |         spec.getParameters().getInvocationId().set(gradle.ext.invocationId) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     gradle.services.get(BuildEventsListenerRegistry).onTaskCompletion(projectTracker) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder.Params>, OperationCompletionListener, AutoCloseable { | ||||||
|  |     private boolean buildFailed = false | ||||||
|  |     interface Params extends BuildServiceParameters { | ||||||
|  |         Property<String> getRootProjectName() | ||||||
|  |         Property<String> getRootProjectDir() | ||||||
|  |         Property<String> getRequestedTasks() | ||||||
|  |         Property<String> getGradleHomeDir() | ||||||
|  |         Property<String> getInvocationId() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void onFinish(FinishEvent finishEvent) { | ||||||
|  |         if (finishEvent instanceof TaskFinishEvent && finishEvent.result instanceof TaskFailureResult) { | ||||||
|  |             buildFailed = true | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void close() { | ||||||
|  |         def buildResults = [ | ||||||
|  |             rootProjectName: getParameters().getRootProjectName().get(), | ||||||
|  |             rootProjectDir: getParameters().getRootProjectDir().get(), | ||||||
|  |             requestedTasks: getParameters().getRequestedTasks().get(), | ||||||
|  |             gradleVersion: GradleVersion.current().version, | ||||||
|  |             gradleHomeDir: getParameters().getGradleHomeDir().get(), | ||||||
|  |             buildFailed: buildFailed, | ||||||
|  |             buildScanUri: null, | ||||||
|  |             buildScanFailed: false | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  |         def runnerTempDir = System.getenv("RUNNER_TEMP") | ||||||
|  |         def githubActionStep = System.getenv("GITHUB_ACTION") | ||||||
|  |         if (!runnerTempDir || !githubActionStep) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         def buildResultsDir = new File(runnerTempDir, ".build-results") | ||||||
|  |         buildResultsDir.mkdirs() | ||||||
|  |         def buildResultsFile = new File(buildResultsDir, githubActionStep + getParameters().getInvocationId().get() + ".json") | ||||||
|  |         buildResultsFile << groovy.json.JsonOutput.toJson(buildResults) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										128
									
								
								src/resources/init-scripts/build-result-capture.init.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/resources/init-scripts/build-result-capture.init.gradle
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | |||||||
|  | /* | ||||||
|  |  * Capture information for each executed Gradle build to display in the job summary. | ||||||
|  |  */ | ||||||
|  | import org.gradle.util.GradleVersion | ||||||
|  | 
 | ||||||
|  | // Only run against root build. Do not run against included builds. | ||||||
|  | def isTopLevelBuild = gradle.getParent() == null | ||||||
|  | if (isTopLevelBuild) { | ||||||
|  |     def version = GradleVersion.current().baseVersion | ||||||
|  | 
 | ||||||
|  |     def atLeastGradle3 = version >= GradleVersion.version("3.0") | ||||||
|  |     def atLeastGradle6 = version >= GradleVersion.version("6.0") | ||||||
|  | 
 | ||||||
|  |     def invocationId = "-${System.currentTimeMillis()}" | ||||||
|  | 
 | ||||||
|  |     if (atLeastGradle6) { | ||||||
|  |         def useBuildService = version >= GradleVersion.version("6.6") | ||||||
|  |         settingsEvaluated { settings -> | ||||||
|  |             // The `buildScanPublished` hook is the only way to capture the build scan URI. | ||||||
|  |             if (settings.pluginManager.hasPlugin("com.gradle.enterprise")) { | ||||||
|  |                 captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject, invocationId) | ||||||
|  |             } | ||||||
|  |             // We also need to add hooks in case the plugin is applied but no build scan is published | ||||||
|  |             if (useBuildService) { | ||||||
|  |                 captureUsingBuildService(settings, invocationId) | ||||||
|  |             } else { | ||||||
|  |                 captureUsingBuildFinished(gradle, invocationId) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } else if (atLeastGradle3) { | ||||||
|  |         projectsEvaluated { gradle -> | ||||||
|  |             if (gradle.rootProject.pluginManager.hasPlugin("com.gradle.build-scan")) { | ||||||
|  |                 captureUsingBuildScanPublished(gradle.rootProject.extensions["buildScan"], gradle.rootProject, invocationId) | ||||||
|  |             } | ||||||
|  |             // We  need to capture in buildFinished in case the plugin is applied but no build scan is published | ||||||
|  |             captureUsingBuildFinished(gradle, invocationId) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId) { | ||||||
|  |     buildScanExtension.with { | ||||||
|  |         def buildResults = new BuildResults(invocationId, gradle, rootProject) | ||||||
|  | 
 | ||||||
|  |         buildFinished { result -> | ||||||
|  |             buildResults.setBuildResult(result) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         buildScanPublished { buildScan -> | ||||||
|  |             buildResults.setBuildScanUri(buildScan.buildScanUri.toASCIIString()) | ||||||
|  |             buildResults.writeToResultsFile(true) | ||||||
|  | 
 | ||||||
|  |             println("::set-output name=build-scan-url::${buildScan.buildScanUri}") | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         onError { error -> | ||||||
|  |             buildResults.setBuildScanFailed() | ||||||
|  |             buildResults.writeToResultsFile(true) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | def captureUsingBuildFinished(gradle, invocationId) { | ||||||
|  |     gradle.buildFinished { result -> | ||||||
|  |         def buildResults = new BuildResults(invocationId, gradle, gradle.rootProject) | ||||||
|  |         buildResults.setBuildResult(result) | ||||||
|  | 
 | ||||||
|  |         buildResults.writeToResultsFile(false) | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | def captureUsingBuildService(settings, invocationId) { | ||||||
|  |     gradle.ext.invocationId = invocationId | ||||||
|  |     apply from: 'build-result-capture-service.plugin.groovy' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class BuildResults { | ||||||
|  |     def invocationId | ||||||
|  |     def buildResults | ||||||
|  | 
 | ||||||
|  |     BuildResults(String invocationId, def gradle, def rootProject) { | ||||||
|  |         this.invocationId = invocationId | ||||||
|  |         buildResults = [ | ||||||
|  |             rootProjectName: rootProject.name, | ||||||
|  |             rootProjectDir: rootProject.projectDir.absolutePath, | ||||||
|  |             requestedTasks: gradle.startParameter.taskNames.join(" "), | ||||||
|  |             gradleVersion: GradleVersion.current().version, | ||||||
|  |             gradleHomeDir: gradle.gradleHomeDir.absolutePath, | ||||||
|  |             buildFailed: false, | ||||||
|  |             buildScanUri: null, | ||||||
|  |             buildScanFailed: false | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def setBuildResult(def result) { | ||||||
|  |         buildResults['buildFailed'] = result.failure != null | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def setBuildScanUri(def buildScanUrl) { | ||||||
|  |         buildResults['buildScanUri'] = buildScanUrl | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def setBuildScanFailed() { | ||||||
|  |         buildResults['buildScanFailed'] = true | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def writeToResultsFile(boolean overwrite) { | ||||||
|  |         def runnerTempDir = System.getenv("RUNNER_TEMP") | ||||||
|  |         def githubActionStep = System.getenv("GITHUB_ACTION") | ||||||
|  |         if (!runnerTempDir || !githubActionStep) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         def buildResultsDir = new File(runnerTempDir, ".build-results") | ||||||
|  |         buildResultsDir.mkdirs() | ||||||
|  |         def buildResultsFile = new File(buildResultsDir, githubActionStep + invocationId + ".json") | ||||||
|  | 
 | ||||||
|  |         // Overwrite any contents written by buildFinished or build service, since this result is a superset. | ||||||
|  |         if (buildResultsFile.exists()) { | ||||||
|  |             if (overwrite) { | ||||||
|  |                 buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults) | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             buildResultsFile << groovy.json.JsonOutput.toJson(buildResults) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										95
									
								
								src/setup-gradle.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/setup-gradle.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import * as exec from '@actions/exec' | ||||||
|  | import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary' | ||||||
|  | import * as path from 'path' | ||||||
|  | import * as os from 'os' | ||||||
|  | import * as caches from './caches' | ||||||
|  | 
 | ||||||
|  | import {logJobSummary, writeJobSummary} from './job-summary' | ||||||
|  | import {loadBuildResults} from './build-results' | ||||||
|  | import {CacheListener} from './cache-reporting' | ||||||
|  | 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' | ||||||
|  | 
 | ||||||
|  | function shouldGenerateJobSummary(): boolean { | ||||||
|  |     // Check if Job Summary is supported on this platform
 | ||||||
|  |     if (!process.env[SUMMARY_ENV_VAR]) { | ||||||
|  |         return false | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function setup(buildRootDirectory: string): Promise<void> { | ||||||
|  |     const gradleUserHome = await 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) | ||||||
|  | 
 | ||||||
|  |     const cacheListener = new CacheListener() | ||||||
|  |     await caches.restore(gradleUserHome, cacheListener) | ||||||
|  | 
 | ||||||
|  |     core.saveState(CACHE_LISTENER, cacheListener.stringify()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function complete(): Promise<void> { | ||||||
|  |     if (!core.getState(GRADLE_SETUP_VAR)) { | ||||||
|  |         core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.') | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  |     core.info('In final post-action step, saving state and writing summary') | ||||||
|  | 
 | ||||||
|  |     const buildResults = loadBuildResults() | ||||||
|  | 
 | ||||||
|  |     const gradleUserHome = core.getState(GRADLE_USER_HOME) | ||||||
|  |     const cacheListener: CacheListener = CacheListener.rehydrate(core.getState(CACHE_LISTENER)) | ||||||
|  |     const daemonController = new DaemonController(buildResults) | ||||||
|  | 
 | ||||||
|  |     await caches.save(gradleUserHome, cacheListener, daemonController) | ||||||
|  | 
 | ||||||
|  |     if (shouldGenerateJobSummary()) { | ||||||
|  |         await writeJobSummary(buildResults, cacheListener) | ||||||
|  |     } else { | ||||||
|  |         logJobSummary(buildResults, cacheListener) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function determineGradleUserHome(rootDir: string): Promise<string> { | ||||||
|  |     const customGradleUserHome = process.env['GRADLE_USER_HOME'] | ||||||
|  |     if (customGradleUserHome) { | ||||||
|  |         return path.resolve(rootDir, customGradleUserHome) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return path.resolve(await determineUserHome(), '.gradle') | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Different values can be returned by os.homedir() in Javascript and System.getProperty('user.home') in Java. | ||||||
|  |  * In order to determine the correct Gradle User Home, we ask Java for the user home instead of using os.homedir(). | ||||||
|  |  */ | ||||||
|  | async function determineUserHome(): Promise<string> { | ||||||
|  |     const output = await exec.getExecOutput('java', ['-XshowSettings:properties', '-version'], {silent: true}) | ||||||
|  |     const regex = /user\.home = (\S*)/i | ||||||
|  |     const found = output.stderr.match(regex) | ||||||
|  |     if (found == null || found.length <= 1) { | ||||||
|  |         core.info('Could not determine user.home from java -version output. Using os.homedir().') | ||||||
|  |         return os.homedir() | ||||||
|  |     } | ||||||
|  |     const userHome = found[1] | ||||||
|  |     core.debug(`Determined user.home from java -version output: '${userHome}'`) | ||||||
|  |     return userHome | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								test/init-scripts/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								test/init-scripts/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | build | ||||||
|  | .gradle | ||||||
							
								
								
									
										29
									
								
								test/init-scripts/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								test/init-scripts/build.gradle
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | plugins { | ||||||
|  |     id 'groovy' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | java { | ||||||
|  |     toolchain { | ||||||
|  |         languageVersion = JavaLanguageVersion.of(8) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | repositories { | ||||||
|  |     mavenCentral() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | dependencies { | ||||||
|  |     testImplementation gradleTestKit() | ||||||
|  |     testImplementation 'org.spockframework:spock-core:2.1-groovy-3.0' | ||||||
|  |     testImplementation('org.spockframework:spock-junit4:2.1-groovy-3.0') | ||||||
|  | 
 | ||||||
|  |     testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') { | ||||||
|  |         exclude group: 'org.codehaus.groovy', module: 'groovy-all' | ||||||
|  |     } | ||||||
|  |     testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.13.3' | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | test { | ||||||
|  |     useJUnitPlatform() | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								test/init-scripts/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/init-scripts/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								test/init-scripts/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								test/init-scripts/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | distributionBase=GRADLE_USER_HOME | ||||||
|  | distributionPath=wrapper/dists | ||||||
|  | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip | ||||||
|  | zipStoreBase=GRADLE_USER_HOME | ||||||
|  | zipStorePath=wrapper/dists | ||||||
							
								
								
									
										234
									
								
								test/init-scripts/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										234
									
								
								test/init-scripts/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @ -0,0 +1,234 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | 
 | ||||||
|  | # | ||||||
|  | # Copyright © 2015-2021 the original authors. | ||||||
|  | # | ||||||
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software | ||||||
|  | # distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and | ||||||
|  | # limitations under the License. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | ############################################################################## | ||||||
|  | # | ||||||
|  | #   Gradle start up script for POSIX generated by Gradle. | ||||||
|  | # | ||||||
|  | #   Important for running: | ||||||
|  | # | ||||||
|  | #   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is | ||||||
|  | #       noncompliant, but you have some other compliant shell such as ksh or | ||||||
|  | #       bash, then to run this script, type that shell name before the whole | ||||||
|  | #       command line, like: | ||||||
|  | # | ||||||
|  | #           ksh Gradle | ||||||
|  | # | ||||||
|  | #       Busybox and similar reduced shells will NOT work, because this script | ||||||
|  | #       requires all of these POSIX shell features: | ||||||
|  | #         * functions; | ||||||
|  | #         * expansions «$var», «${var}», «${var:-default}», «${var+SET}», | ||||||
|  | #           «${var#prefix}», «${var%suffix}», and «$( cmd )»; | ||||||
|  | #         * compound commands having a testable exit status, especially «case»; | ||||||
|  | #         * various built-in commands including «command», «set», and «ulimit». | ||||||
|  | # | ||||||
|  | #   Important for patching: | ||||||
|  | # | ||||||
|  | #   (2) This script targets any POSIX shell, so it avoids extensions provided | ||||||
|  | #       by Bash, Ksh, etc; in particular arrays are avoided. | ||||||
|  | # | ||||||
|  | #       The "traditional" practice of packing multiple parameters into a | ||||||
|  | #       space-separated string is a well documented source of bugs and security | ||||||
|  | #       problems, so this is (mostly) avoided, by progressively accumulating | ||||||
|  | #       options in "$@", and eventually passing that to Java. | ||||||
|  | # | ||||||
|  | #       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, | ||||||
|  | #       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; | ||||||
|  | #       see the in-line comments for details. | ||||||
|  | # | ||||||
|  | #       There are tweaks for specific operating systems such as AIX, CygWin, | ||||||
|  | #       Darwin, MinGW, and NonStop. | ||||||
|  | # | ||||||
|  | #   (3) This script is generated from the Groovy template | ||||||
|  | #       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||||
|  | #       within the Gradle project. | ||||||
|  | # | ||||||
|  | #       You can find Gradle at https://github.com/gradle/gradle/. | ||||||
|  | # | ||||||
|  | ############################################################################## | ||||||
|  | 
 | ||||||
|  | # Attempt to set APP_HOME | ||||||
|  | 
 | ||||||
|  | # Resolve links: $0 may be a link | ||||||
|  | app_path=$0 | ||||||
|  | 
 | ||||||
|  | # Need this for daisy-chained symlinks. | ||||||
|  | while | ||||||
|  |     APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path | ||||||
|  |     [ -h "$app_path" ] | ||||||
|  | do | ||||||
|  |     ls=$( ls -ld "$app_path" ) | ||||||
|  |     link=${ls#*' -> '} | ||||||
|  |     case $link in             #( | ||||||
|  |       /*)   app_path=$link ;; #( | ||||||
|  |       *)    app_path=$APP_HOME$link ;; | ||||||
|  |     esac | ||||||
|  | done | ||||||
|  | 
 | ||||||
|  | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | ||||||
|  | 
 | ||||||
|  | APP_NAME="Gradle" | ||||||
|  | APP_BASE_NAME=${0##*/} | ||||||
|  | 
 | ||||||
|  | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
|  | 
 | ||||||
|  | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
|  | MAX_FD=maximum | ||||||
|  | 
 | ||||||
|  | warn () { | ||||||
|  |     echo "$*" | ||||||
|  | } >&2 | ||||||
|  | 
 | ||||||
|  | die () { | ||||||
|  |     echo | ||||||
|  |     echo "$*" | ||||||
|  |     echo | ||||||
|  |     exit 1 | ||||||
|  | } >&2 | ||||||
|  | 
 | ||||||
|  | # OS specific support (must be 'true' or 'false'). | ||||||
|  | cygwin=false | ||||||
|  | msys=false | ||||||
|  | darwin=false | ||||||
|  | nonstop=false | ||||||
|  | case "$( uname )" in                #( | ||||||
|  |   CYGWIN* )         cygwin=true  ;; #( | ||||||
|  |   Darwin* )         darwin=true  ;; #( | ||||||
|  |   MSYS* | MINGW* )  msys=true    ;; #( | ||||||
|  |   NONSTOP* )        nonstop=true ;; | ||||||
|  | esac | ||||||
|  | 
 | ||||||
|  | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Determine the Java command to use to start the JVM. | ||||||
|  | if [ -n "$JAVA_HOME" ] ; then | ||||||
|  |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||||||
|  |         # IBM's JDK on AIX uses strange locations for the executables | ||||||
|  |         JAVACMD=$JAVA_HOME/jre/sh/java | ||||||
|  |     else | ||||||
|  |         JAVACMD=$JAVA_HOME/bin/java | ||||||
|  |     fi | ||||||
|  |     if [ ! -x "$JAVACMD" ] ; then | ||||||
|  |         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||||||
|  | 
 | ||||||
|  | Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | location of your Java installation." | ||||||
|  |     fi | ||||||
|  | else | ||||||
|  |     JAVACMD=java | ||||||
|  |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|  | 
 | ||||||
|  | Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | location of your Java installation." | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # Increase the maximum file descriptors if we can. | ||||||
|  | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||||
|  |     case $MAX_FD in #( | ||||||
|  |       max*) | ||||||
|  |         MAX_FD=$( ulimit -H -n ) || | ||||||
|  |             warn "Could not query maximum file descriptor limit" | ||||||
|  |     esac | ||||||
|  |     case $MAX_FD in  #( | ||||||
|  |       '' | soft) :;; #( | ||||||
|  |       *) | ||||||
|  |         ulimit -n "$MAX_FD" || | ||||||
|  |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
|  |     esac | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # Collect all arguments for the java command, stacking in reverse order: | ||||||
|  | #   * args from the command line | ||||||
|  | #   * the main class name | ||||||
|  | #   * -classpath | ||||||
|  | #   * -D...appname settings | ||||||
|  | #   * --module-path (only if needed) | ||||||
|  | #   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. | ||||||
|  | 
 | ||||||
|  | # For Cygwin or MSYS, switch paths to Windows format before running java | ||||||
|  | if "$cygwin" || "$msys" ; then | ||||||
|  |     APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) | ||||||
|  |     CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) | ||||||
|  | 
 | ||||||
|  |     JAVACMD=$( cygpath --unix "$JAVACMD" ) | ||||||
|  | 
 | ||||||
|  |     # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||||||
|  |     for arg do | ||||||
|  |         if | ||||||
|  |             case $arg in                                #( | ||||||
|  |               -*)   false ;;                            # don't mess with options #( | ||||||
|  |               /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath | ||||||
|  |                     [ -e "$t" ] ;;                      #( | ||||||
|  |               *)    false ;; | ||||||
|  |             esac | ||||||
|  |         then | ||||||
|  |             arg=$( cygpath --path --ignore --mixed "$arg" ) | ||||||
|  |         fi | ||||||
|  |         # Roll the args list around exactly as many times as the number of | ||||||
|  |         # args, so each arg winds up back in the position where it started, but | ||||||
|  |         # possibly modified. | ||||||
|  |         # | ||||||
|  |         # NB: a `for` loop captures its iteration list before it begins, so | ||||||
|  |         # changing the positional parameters here affects neither the number of | ||||||
|  |         # iterations, nor the values presented in `arg`. | ||||||
|  |         shift                   # remove old arg | ||||||
|  |         set -- "$@" "$arg"      # push replacement arg | ||||||
|  |     done | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # Collect all arguments for the java command; | ||||||
|  | #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | ||||||
|  | #     shell script including quotes and variable substitutions, so put them in | ||||||
|  | #     double quotes to make sure that they get re-expanded; and | ||||||
|  | #   * put everything else in single quotes, so that it's not re-expanded. | ||||||
|  | 
 | ||||||
|  | set -- \ | ||||||
|  |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|  |         -classpath "$CLASSPATH" \ | ||||||
|  |         org.gradle.wrapper.GradleWrapperMain \ | ||||||
|  |         "$@" | ||||||
|  | 
 | ||||||
|  | # Use "xargs" to parse quoted args. | ||||||
|  | # | ||||||
|  | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. | ||||||
|  | # | ||||||
|  | # In Bash we could simply go: | ||||||
|  | # | ||||||
|  | #   readarray ARGS < <( xargs -n1 <<<"$var" ) && | ||||||
|  | #   set -- "${ARGS[@]}" "$@" | ||||||
|  | # | ||||||
|  | # but POSIX shell has neither arrays nor command substitution, so instead we | ||||||
|  | # post-process each arg (as a line of input to sed) to backslash-escape any | ||||||
|  | # character that might be a shell metacharacter, then use eval to reverse | ||||||
|  | # that process (while maintaining the separation between arguments), and wrap | ||||||
|  | # the whole thing up as a single "set" statement. | ||||||
|  | # | ||||||
|  | # This will of course break if any of these variables contains a newline or | ||||||
|  | # an unmatched quote. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | eval "set -- $( | ||||||
|  |         printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | | ||||||
|  |         xargs -n1 | | ||||||
|  |         sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | | ||||||
|  |         tr '\n' ' ' | ||||||
|  |     )" '"$@"' | ||||||
|  | 
 | ||||||
|  | exec "$JAVACMD" "$@" | ||||||
							
								
								
									
										89
									
								
								test/init-scripts/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								test/init-scripts/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | |||||||
|  | @rem | ||||||
|  | @rem Copyright 2015 the original author or authors. | ||||||
|  | @rem | ||||||
|  | @rem Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | @rem you may not use this file except in compliance with the License. | ||||||
|  | @rem You may obtain a copy of the License at | ||||||
|  | @rem | ||||||
|  | @rem      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | @rem | ||||||
|  | @rem Unless required by applicable law or agreed to in writing, software | ||||||
|  | @rem distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | @rem See the License for the specific language governing permissions and | ||||||
|  | @rem limitations under the License. | ||||||
|  | @rem | ||||||
|  | 
 | ||||||
|  | @if "%DEBUG%" == "" @echo off | ||||||
|  | @rem ########################################################################## | ||||||
|  | @rem | ||||||
|  | @rem  Gradle startup script for Windows | ||||||
|  | @rem | ||||||
|  | @rem ########################################################################## | ||||||
|  | 
 | ||||||
|  | @rem Set local scope for the variables with windows NT shell | ||||||
|  | if "%OS%"=="Windows_NT" setlocal | ||||||
|  | 
 | ||||||
|  | set DIRNAME=%~dp0 | ||||||
|  | if "%DIRNAME%" == "" set DIRNAME=. | ||||||
|  | set APP_BASE_NAME=%~n0 | ||||||
|  | set APP_HOME=%DIRNAME% | ||||||
|  | 
 | ||||||
|  | @rem Resolve any "." and ".." in APP_HOME to make it shorter. | ||||||
|  | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | ||||||
|  | 
 | ||||||
|  | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | ||||||
|  | 
 | ||||||
|  | @rem Find java.exe | ||||||
|  | if defined JAVA_HOME goto findJavaFromJavaHome | ||||||
|  | 
 | ||||||
|  | set JAVA_EXE=java.exe | ||||||
|  | %JAVA_EXE% -version >NUL 2>&1 | ||||||
|  | if "%ERRORLEVEL%" == "0" goto execute | ||||||
|  | 
 | ||||||
|  | echo. | ||||||
|  | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|  | echo. | ||||||
|  | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | echo location of your Java installation. | ||||||
|  | 
 | ||||||
|  | goto fail | ||||||
|  | 
 | ||||||
|  | :findJavaFromJavaHome | ||||||
|  | set JAVA_HOME=%JAVA_HOME:"=% | ||||||
|  | set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||||||
|  | 
 | ||||||
|  | if exist "%JAVA_EXE%" goto execute | ||||||
|  | 
 | ||||||
|  | echo. | ||||||
|  | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
|  | echo. | ||||||
|  | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | echo location of your Java installation. | ||||||
|  | 
 | ||||||
|  | goto fail | ||||||
|  | 
 | ||||||
|  | :execute | ||||||
|  | @rem Setup the command line | ||||||
|  | 
 | ||||||
|  | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @rem Execute Gradle | ||||||
|  | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | ||||||
|  | 
 | ||||||
|  | :end | ||||||
|  | @rem End local scope for the variables with windows NT shell | ||||||
|  | if "%ERRORLEVEL%"=="0" goto mainEnd | ||||||
|  | 
 | ||||||
|  | :fail | ||||||
|  | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||||||
|  | rem the _cmd.exe /c_ return code! | ||||||
|  | if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||||||
|  | exit /b 1 | ||||||
|  | 
 | ||||||
|  | :mainEnd | ||||||
|  | if "%OS%"=="Windows_NT" endlocal | ||||||
|  | 
 | ||||||
|  | :omega | ||||||
							
								
								
									
										1
									
								
								test/init-scripts/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/init-scripts/settings.gradle
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | rootProject.name = 'test-init-scripts' | ||||||
| @ -0,0 +1,250 @@ | |||||||
|  | package com.gradle.gradlebuildaction | ||||||
|  | 
 | ||||||
|  | import com.fasterxml.jackson.core.JsonFactory | ||||||
|  | import com.fasterxml.jackson.databind.ObjectMapper | ||||||
|  | import com.fasterxml.jackson.dataformat.smile.SmileFactory | ||||||
|  | import org.gradle.testkit.runner.BuildResult | ||||||
|  | import org.gradle.testkit.runner.GradleRunner | ||||||
|  | import org.gradle.testkit.runner.internal.DefaultGradleRunner | ||||||
|  | import org.gradle.util.GradleVersion | ||||||
|  | import ratpack.groovy.test.embed.GroovyEmbeddedApp | ||||||
|  | import spock.lang.AutoCleanup | ||||||
|  | import spock.lang.Specification | ||||||
|  | import spock.lang.TempDir | ||||||
|  | 
 | ||||||
|  | import java.nio.file.Files | ||||||
|  | import java.util.zip.GZIPOutputStream | ||||||
|  | 
 | ||||||
|  | class BaseInitScriptTest extends Specification { | ||||||
|  | 
 | ||||||
|  |     static final TestGradleVersion GRADLE_3_5 = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9) | ||||||
|  |     static final TestGradleVersion GRADLE_4_0 = new TestGradleVersion(GradleVersion.version('4.0.2'), 7, 9) | ||||||
|  |     static final TestGradleVersion GRADLE_4_10 = new TestGradleVersion(GradleVersion.version('4.10.3'), 7, 10) | ||||||
|  |     static final TestGradleVersion GRADLE_5_0 = new TestGradleVersion(GradleVersion.version('5.0'), 8, 11) | ||||||
|  |     static final TestGradleVersion GRADLE_5_6 = new TestGradleVersion(GradleVersion.version('5.6.4'), 8, 12) | ||||||
|  |     static final TestGradleVersion GRADLE_6_0 = new TestGradleVersion(GradleVersion.version('6.0.1'), 8, 13) | ||||||
|  |     static final TestGradleVersion GRADLE_6_7 = new TestGradleVersion(GradleVersion.version('6.7'), 8, 15) | ||||||
|  |     static final TestGradleVersion GRADLE_7_0 = new TestGradleVersion(GradleVersion.version('7.0.2'), 8, 16) | ||||||
|  |     static final TestGradleVersion GRADLE_7_4 = new TestGradleVersion(GradleVersion.version('7.4.2'), 8, 17) | ||||||
|  | 
 | ||||||
|  |     static final List<TestGradleVersion> ALL_VERSIONS = [ | ||||||
|  |         GRADLE_3_5, // First version where TestKit supports environment variables | ||||||
|  |         GRADLE_4_0, | ||||||
|  |         GRADLE_4_10, | ||||||
|  |         GRADLE_5_0, | ||||||
|  |         GRADLE_5_6, | ||||||
|  |         GRADLE_6_0, | ||||||
|  |         GRADLE_6_7, | ||||||
|  |         GRADLE_7_0, | ||||||
|  |         GRADLE_7_4, | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     static final List<TestGradleVersion> CONFIGURATION_CACHE_VERSIONS = | ||||||
|  |         [GRADLE_7_0, GRADLE_7_4] | ||||||
|  | 
 | ||||||
|  |     static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw' | ||||||
|  |     static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token' | ||||||
|  |     static final String ROOT_PROJECT_NAME = 'test-init-script' | ||||||
|  |     boolean failScanUpload = false | ||||||
|  | 
 | ||||||
|  |     File settingsFile | ||||||
|  |     File buildFile | ||||||
|  | 
 | ||||||
|  |     @TempDir | ||||||
|  |     File testProjectDir | ||||||
|  | 
 | ||||||
|  |     @AutoCleanup | ||||||
|  |     def mockScansServer = GroovyEmbeddedApp.of { | ||||||
|  |         def jsonWriter = new ObjectMapper(new JsonFactory()).writer() | ||||||
|  |         def smileWriter = new ObjectMapper(new SmileFactory()).writer() | ||||||
|  | 
 | ||||||
|  |         handlers { | ||||||
|  |             post('in/:gradleVersion/:pluginVersion') { | ||||||
|  |                 if (failScanUpload) { | ||||||
|  |                     context.response.status(401).send() | ||||||
|  |                     return | ||||||
|  |                 } | ||||||
|  |                 def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID" | ||||||
|  |                 def body = [ | ||||||
|  |                     id     : PUBLIC_BUILD_SCAN_ID, | ||||||
|  |                     scanUrl: scanUrlString.toString(), | ||||||
|  |                 ] | ||||||
|  |                 def out = new ByteArrayOutputStream() | ||||||
|  |                 new GZIPOutputStream(out).withStream { smileWriter.writeValue(it, body) } | ||||||
|  |                 context.response | ||||||
|  |                     .contentType('application/vnd.gradle.scan-ack') | ||||||
|  |                     .send(out.toByteArray()) | ||||||
|  |             } | ||||||
|  |             prefix('scans/publish') { | ||||||
|  |                 post('gradle/:pluginVersion/token') { | ||||||
|  |                     if (failScanUpload) { | ||||||
|  |                         context.response.status(401).send() | ||||||
|  |                         return | ||||||
|  |                     } | ||||||
|  |                     def pluginVersion = context.pathTokens.pluginVersion | ||||||
|  |                     def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID" | ||||||
|  |                     def body = [ | ||||||
|  |                         id             : PUBLIC_BUILD_SCAN_ID, | ||||||
|  |                         scanUrl        : scanUrlString.toString(), | ||||||
|  |                         scanUploadUrl  : "${mockScansServer.address.toString()}scans/publish/gradle/$pluginVersion/upload".toString(), | ||||||
|  |                         scanUploadToken: DEFAULT_SCAN_UPLOAD_TOKEN | ||||||
|  |                     ] | ||||||
|  |                     context.response | ||||||
|  |                         .contentType('application/vnd.gradle.scan-ack+json') | ||||||
|  |                         .send(jsonWriter.writeValueAsBytes(body)) | ||||||
|  |                 } | ||||||
|  |                 post('gradle/:pluginVersion/upload') { | ||||||
|  |                     if (failScanUpload) { | ||||||
|  |                         context.response.status(401).send() | ||||||
|  |                         return | ||||||
|  |                     } | ||||||
|  |                     context.request.getBody(1024 * 1024 * 10).then { | ||||||
|  |                         context.response | ||||||
|  |                             .contentType('application/vnd.gradle.scan-upload-ack+json') | ||||||
|  |                             .send() | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 notFound() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def setup() { | ||||||
|  |         settingsFile = new File(testProjectDir, 'settings.gradle') | ||||||
|  |         buildFile = new File(testProjectDir, 'build.gradle') | ||||||
|  | 
 | ||||||
|  |         File srcInitScriptsDir = new File("../../src/resources/init-scripts") | ||||||
|  |         File targetInitScriptsDir = new File(testProjectDir, "initScripts") | ||||||
|  |         targetInitScriptsDir.mkdirs() | ||||||
|  | 
 | ||||||
|  |         for (File srcInitScript : srcInitScriptsDir.listFiles()) { | ||||||
|  |             File targetInitScript = new File(targetInitScriptsDir, srcInitScript.name) | ||||||
|  |             Files.copy(srcInitScript.toPath(), targetInitScript.toPath()) | ||||||
|  |         } | ||||||
|  |         settingsFile << "rootProject.name = '${ROOT_PROJECT_NAME}'\n" | ||||||
|  |         buildFile << '' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def declareGePluginApplication(GradleVersion gradleVersion) { | ||||||
|  |         settingsFile.text = maybeAddPluginsToSettings(gradleVersion) + settingsFile.text | ||||||
|  |         buildFile.text = maybeAddPluginsToRootProject(gradleVersion) + buildFile.text | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     String maybeAddPluginsToSettings(GradleVersion gradleVersion) { | ||||||
|  |         if (gradleVersion < GradleVersion.version('5.0')) { | ||||||
|  |             '' // applied in build.gradle | ||||||
|  |         } else if (gradleVersion < GradleVersion.version('6.0')) { | ||||||
|  |             '' // applied in build.gradle | ||||||
|  |         } else { | ||||||
|  |             """ | ||||||
|  |               plugins { | ||||||
|  |                 id 'com.gradle.enterprise' version '3.4.1' | ||||||
|  |               } | ||||||
|  |               gradleEnterprise { | ||||||
|  |                 server = '$mockScansServer.address' | ||||||
|  |                 buildScan { | ||||||
|  |                   publishAlways() | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |             """ | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     String maybeAddPluginsToRootProject(GradleVersion gradleVersion) { | ||||||
|  |         if (gradleVersion < GradleVersion.version('5.0')) { | ||||||
|  |             """ | ||||||
|  |               plugins { | ||||||
|  |                 id 'com.gradle.build-scan' version '1.16' | ||||||
|  |               } | ||||||
|  |               buildScan { | ||||||
|  |                 server = '$mockScansServer.address' | ||||||
|  |                 publishAlways() | ||||||
|  |               } | ||||||
|  |             """ | ||||||
|  |         } else if (gradleVersion < GradleVersion.version('6.0')) { | ||||||
|  |             """ | ||||||
|  |               plugins { | ||||||
|  |                 id 'com.gradle.build-scan' version '3.4.1' | ||||||
|  |               } | ||||||
|  |               gradleEnterprise { | ||||||
|  |                 server = '$mockScansServer.address' | ||||||
|  |                 buildScan { | ||||||
|  |                   publishAlways() | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |             """ | ||||||
|  |         } else { | ||||||
|  |             '' // applied in settings.gradle | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def addFailingTaskToBuild() { | ||||||
|  |         buildFile << ''' | ||||||
|  | task expectFailure { | ||||||
|  |     doLast { | ||||||
|  |         throw new RuntimeException("Expected to fail") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | ''' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     BuildResult run(List<String> args, String initScript, GradleVersion gradleVersion = GradleVersion.current(), List<String> jvmArgs = [], Map<String, String> envVars = [:]) { | ||||||
|  |         createRunner(initScript, args, gradleVersion, jvmArgs, envVars).build() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     BuildResult runAndFail(List<String> args, String initScript, GradleVersion gradleVersion = GradleVersion.current(), List<String> jvmArgs = [], Map<String, String> envVars = [:]) { | ||||||
|  |         createRunner(initScript, args, gradleVersion, jvmArgs, envVars).buildAndFail() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     GradleRunner createRunner(String initScript, List<String> args, GradleVersion gradleVersion = GradleVersion.current(), List<String> jvmArgs = [], Map<String, String> envVars = [:]) { | ||||||
|  |         File initScriptsDir = new File(testProjectDir, "initScripts") | ||||||
|  |         args << '-I' << new File(initScriptsDir, initScript).absolutePath | ||||||
|  | 
 | ||||||
|  |         envVars.putIfAbsent('RUNNER_TEMP', testProjectDir.absolutePath) | ||||||
|  |         envVars.putIfAbsent('GITHUB_ACTION', 'github-step-id') | ||||||
|  | 
 | ||||||
|  |         def runner = ((DefaultGradleRunner) GradleRunner.create()) | ||||||
|  |             .withJvmArguments(jvmArgs) | ||||||
|  |             .withGradleVersion(gradleVersion.version) | ||||||
|  |             .withProjectDir(testProjectDir) | ||||||
|  |             .withArguments(args) | ||||||
|  |             .withEnvironment(envVars) | ||||||
|  |             .forwardOutput() | ||||||
|  | 
 | ||||||
|  |         runner | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static final class TestGradleVersion { | ||||||
|  | 
 | ||||||
|  |         final GradleVersion gradleVersion | ||||||
|  |         private final Integer jdkMin | ||||||
|  |         private final Integer jdkMax | ||||||
|  | 
 | ||||||
|  |         TestGradleVersion(GradleVersion gradleVersion, Integer jdkMin, Integer jdkMax) { | ||||||
|  |             this.gradleVersion = gradleVersion | ||||||
|  |             this.jdkMin = jdkMin | ||||||
|  |             this.jdkMax = jdkMax | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         boolean isCompatibleWithCurrentJvm() { | ||||||
|  |             def jvmVersion = getJvmVersion() | ||||||
|  |             jdkMin <= jvmVersion && jvmVersion <= jdkMax | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private static int getJvmVersion() { | ||||||
|  |             String version = System.getProperty('java.version') | ||||||
|  |             if (version.startsWith('1.')) { | ||||||
|  |                 Integer.parseInt(version.substring(2, 3)) | ||||||
|  |             } else { | ||||||
|  |                 Integer.parseInt(version.substring(0, version.indexOf('.'))) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         String toString() { | ||||||
|  |             return "Gradle " + gradleVersion.version | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user