Compare commits

...

53 Commits

Author SHA1 Message Date
Daz DeBoer
cd3cedc781 Merge pull request #365 from gradle/wrapperbot/gradle-build-action-sample-groovy-dsl/gradle-wrapper-7.5
Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/groovy-dsl
2022-07-16 15:48:19 -06:00
Daz DeBoer
e54bfe60d4 Update check for new Gradle version 2022-07-16 15:44:18 -06:00
Alexis Tual
d70ff19b06 Merge pull request #364 from gradle/wrapperbot/gradle-build-action-sample-gradle-plugin/gradle-wrapper-7.5
Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/gradle-plugin
2022-07-15 15:48:44 +02:00
Alexis Tual
45417006b1 Merge pull request #366 from gradle/wrapperbot/gradle-build-action-sample-java-toolchain/gradle-wrapper-7.5
Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/java-toolchain
2022-07-15 15:44:02 +02:00
Alexis Tual
925e60d017 Merge pull request #367 from gradle/wrapperbot/gradle-build-action-sample-kotlin-dsl/gradle-wrapper-7.5
Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/kotlin-dsl
2022-07-15 15:39:31 +02:00
bot-githubaction
47a028a7f5 Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/kotlin-dsl 2022-07-15 03:00:29 +00:00
bot-githubaction
7df347a3ca Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/java-toolchain 2022-07-15 03:00:02 +00:00
bot-githubaction
d742f2f6db Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/groovy-dsl 2022-07-15 02:59:55 +00:00
bot-githubaction
e4c0d1d512 Bump Gradle Wrapper from 7.4.2 to 7.5 in /.github/workflow-samples/gradle-plugin 2022-07-15 02:59:44 +00:00
Clay Johnson
64a1064eca Merge pull request #363 from gradle/dependabot/gradle/dot-github/workflow-samples/no-wrapper-gradle-5/com.gradle.build-scan-3.10.3
Bump com.gradle.build-scan from 3.10.2 to 3.10.3 in /.github/workflow-samples/no-wrapper-gradle-5
2022-07-12 06:59:42 -05:00
Clay Johnson
bc57473979 Merge pull request #362 from gradle/dependabot/gradle/dot-github/workflow-samples/groovy-dsl/com.gradle.enterprise-3.10.3
Bump com.gradle.enterprise from 3.10.2 to 3.10.3 in /.github/workflow-samples/groovy-dsl
2022-07-12 06:59:33 -05:00
Clay Johnson
11ea84dec5 Merge pull request #361 from gradle/dependabot/gradle/dot-github/workflow-samples/no-wrapper/com.gradle.enterprise-3.10.3
Bump com.gradle.enterprise from 3.10.2 to 3.10.3 in /.github/workflow-samples/no-wrapper
2022-07-12 06:59:25 -05:00
Clay Johnson
5a614fb332 Merge pull request #360 from gradle/dependabot/gradle/dot-github/workflow-samples/kotlin-dsl/com.gradle.enterprise-3.10.3
Bump com.gradle.enterprise from 3.10.2 to 3.10.3 in /.github/workflow-samples/kotlin-dsl
2022-07-12 06:58:31 -05:00
Clay Johnson
d3a8ea948b Merge pull request #359 from gradle/dependabot/npm_and_yarn/typescript-eslint/parser-5.30.6
Bump @typescript-eslint/parser from 5.30.5 to 5.30.6
2022-07-12 06:57:50 -05:00
dependabot[bot]
fba23f26a1 Bump com.gradle.build-scan
Bumps com.gradle.build-scan from 3.10.2 to 3.10.3.

---
updated-dependencies:
- dependency-name: com.gradle.build-scan
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 22:53:08 +00:00
dependabot[bot]
683f9d4247 Bump com.gradle.enterprise in /.github/workflow-samples/groovy-dsl
Bumps com.gradle.enterprise from 3.10.2 to 3.10.3.

---
updated-dependencies:
- dependency-name: com.gradle.enterprise
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 22:51:44 +00:00
dependabot[bot]
f87d5a33c9 Bump com.gradle.enterprise in /.github/workflow-samples/no-wrapper
Bumps com.gradle.enterprise from 3.10.2 to 3.10.3.

---
updated-dependencies:
- dependency-name: com.gradle.enterprise
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 22:51:42 +00:00
dependabot[bot]
42014fb4fa Bump com.gradle.enterprise in /.github/workflow-samples/kotlin-dsl
Bumps com.gradle.enterprise from 3.10.2 to 3.10.3.

---
updated-dependencies:
- dependency-name: com.gradle.enterprise
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 22:51:39 +00:00
dependabot[bot]
2da06d5689 Bump @typescript-eslint/parser from 5.30.5 to 5.30.6
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.30.5 to 5.30.6.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.30.6/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 22:41:24 +00:00
Daz DeBoer
792a93a5e3 Do not write build-results file outside GitHub Actions context
The init-scripts added to Gradle User Home were assuming the presence of certain
GitHub Actions environment variables. With this fix, these init scripts behave
better without these env vars.

Fixes #350
2022-07-11 15:09:56 -06:00
Daz DeBoer
86da5e6c4e Merge pull request #349 from gradle/dependabot/npm_and_yarn/actions/cache-3.0.0
Bump @actions/cache from 2.0.6 to 3.0.0
2022-07-11 13:48:43 -06:00
Daz DeBoer
6daf446e27 Build outputs 2022-07-11 13:37:59 -06:00
Daz DeBoer
8a8f74b15c Updated patch for actions/cache v3.0.0 2022-07-11 13:36:42 -06:00
Daz DeBoer
15453523bd Improve documentation of cache-read-only 2022-07-11 12:27:54 -06:00
Clay Johnson
b1b0eab63d Merge pull request #357 from gradle/dependabot/npm_and_yarn/eslint-8.19.0
Bump eslint from 8.18.0 to 8.19.0
2022-07-11 09:23:54 -05:00
dependabot[bot]
f580ce7b99 Bump eslint from 8.18.0 to 8.19.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.18.0 to 8.19.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.18.0...v8.19.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-05 12:45:59 +00:00
Clay Johnson
2a7ffc9c95 Merge pull request #355 from gradle/dependabot/npm_and_yarn/typescript-eslint/parser-5.30.5
Bump @typescript-eslint/parser from 5.30.0 to 5.30.5
2022-07-05 07:45:09 -05:00
Clay Johnson
ff6b0e0388 Merge pull request #351 from SIMULATAN/fix-readme-typo
Fix typo in README.md
2022-07-05 07:42:24 -05:00
dependabot[bot]
71e1e1b52b Bump @typescript-eslint/parser from 5.30.0 to 5.30.5
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.30.0 to 5.30.5.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.30.5/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-05 12:41:53 +00:00
Clay Johnson
02b67b8bfe Merge pull request #356 from gradle/dependabot/npm_and_yarn/jest-and-types/jest-28.1.2
Bump jest and @types/jest
2022-07-05 07:41:13 -05:00
dependabot[bot]
5ce69a34b6 Bump jest and @types/jest
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) and [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest). These dependencies needed to be updated together.

Updates `jest` from 28.1.1 to 28.1.2
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v28.1.2/packages/jest)

Updates `@types/jest` from 28.1.3 to 28.1.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 22:21:18 +00:00
Jakob
e7f3e4d839 Fix typo in README.md
exising -> existing

Signed-off-by: SIMULATAN <simulatan2319@gmail.com>
2022-07-03 12:29:54 +02:00
Clay Johnson
7645d3e274 Merge pull request #348 from gradle/dependabot/npm_and_yarn/typescript-eslint/parser-5.30.0
Bump @typescript-eslint/parser from 5.29.0 to 5.30.0
2022-06-28 07:46:40 -05:00
dependabot[bot]
be13141ec7 Bump @typescript-eslint/parser from 5.29.0 to 5.30.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.29.0 to 5.30.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.30.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-28 12:41:21 +00:00
Clay Johnson
db33711f5a Merge pull request #347 from gradle/dependabot/npm_and_yarn/types/jest-28.1.3
Bump @types/jest from 28.1.2 to 28.1.3
2022-06-28 07:40:40 -05:00
dependabot[bot]
84dee23dd9 Bump @actions/cache from 2.0.6 to 3.0.0
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 2.0.6 to 3.0.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

---
updated-dependencies:
- dependency-name: "@actions/cache"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 22:14:28 +00:00
dependabot[bot]
a603ab7405 Bump @types/jest from 28.1.2 to 28.1.3
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 28.1.2 to 28.1.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 22:13:57 +00:00
Daz DeBoer
bc41b8f654 Merge pull request #344 from gradle/dd/issue341
Only stop Gradle Daemons when saving Gradle User Home state
2022-06-23 09:32:56 -06:00
Daz DeBoer
32923891b5 Note daemon stopping behaviour in README
Text provided by @milis92
2022-06-22 16:52:00 -06:00
Daz DeBoer
fecf3693b5 Build outputs 2022-06-22 16:41:13 -06:00
Daz DeBoer
6965e8ed4c Only stop Gradle Daemons when saving Gradle User Home state
Fixes #341
2022-06-22 16:41:03 -06:00
Daz DeBoer
884bca012f Extracted some classes and refactored for clarity 2022-06-22 16:35:55 -06:00
Daz DeBoer
7f46dbd76f Document support for GitHub Enterprise Server 2022-06-20 20:46:57 -06:00
Daz DeBoer
ea4554d4d2 Merge pull request #340 from gradle/dd/github-enterprise-support
Improve support for GitHub Enterprise
2022-06-20 20:35:44 -06:00
Daz DeBoer
d8b58e3519 Build outputs 2022-06-20 20:18:17 -06:00
Daz DeBoer
4cb86e9712 Report when cache not available 2022-06-20 20:17:36 -06:00
Daz DeBoer
eaed5520c4 Write job summary to logs when feature not available 2022-06-20 20:10:34 -06:00
Daz DeBoer
ec939a8c10 Disable caching when feature not available 2022-06-20 18:11:11 -06:00
Daz DeBoer
6594e9d359 Update dev dependencies 2022-06-20 18:08:11 -06:00
Daz DeBoer
52e6e7d89f Run verify outputs for dependabot PRs 2022-06-20 18:06:38 -06:00
Daz DeBoer
2bf1894aa3 Merge pull request #334 from gradle/dependabot/npm_and_yarn/actions/core-1.9.0
Bump @actions/core from 1.8.2 to 1.9.0
2022-06-20 17:59:47 -06:00
dependabot[bot]
795895fc71 Bump @actions/core from 1.8.2 to 1.9.0
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.8.2 to 1.9.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 22:22:14 +00:00
Daz DeBoer
98376690f1 Update changelog post-release 2022-06-20 09:02:53 -06:00
43 changed files with 1320 additions and 1614 deletions

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionSha256Sum=cb87f222c5585bd46838ad4db78463a5c5f3d336e5e2b98dc7c0c586527351c2
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

View File

@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 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
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionSha256Sum=cb87f222c5585bd46838ad4db78463a5c5f3d336e5e2b98dc7c0c586527351c2
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

View File

@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 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
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View File

@@ -1,5 +1,5 @@
plugins {
id "com.gradle.enterprise" version "3.10.2"
id "com.gradle.enterprise" version "3.10.3"
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.7.2"
}

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionSha256Sum=cb87f222c5585bd46838ad4db78463a5c5f3d336e5e2b98dc7c0c586527351c2
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

View File

@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 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
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionSha256Sum=cb87f222c5585bd46838ad4db78463a5c5f3d336e5e2b98dc7c0c586527351c2
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

View File

@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 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
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View File

@@ -1,5 +1,5 @@
plugins {
id("com.gradle.enterprise") version "3.10.2"
id("com.gradle.enterprise") version "3.10.3"
id("com.gradle.common-custom-user-data-gradle-plugin") version "1.7.2"
}

View File

@@ -1,5 +1,5 @@
plugins {
id "com.gradle.build-scan" version "3.10.2"
id "com.gradle.build-scan" version "3.10.3"
}
gradleEnterprise {

View File

@@ -1,5 +1,5 @@
plugins {
id "com.gradle.enterprise" version "3.10.2"
id "com.gradle.enterprise" version "3.10.3"
}
gradleEnterprise {

View File

@@ -8,6 +8,7 @@ on:
push:
branches:
- main
- dependabot/**
jobs:
check:

View File

@@ -51,7 +51,7 @@ jobs:
with:
gradle-executable: .github/workflow-samples/groovy-dsl/gradlew${{ matrix.script-suffix }}
build-root-directory: .github/workflow-samples/no-wrapper
arguments: help -DgradleVersionCheck=7.4.2
arguments: help -DgradleVersionCheck=7.5
gradle-versions:
strategy:

View File

@@ -205,7 +205,6 @@ 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.
@@ -234,6 +233,13 @@ You can configure read-only caching for the `gradle-build-action` as follows:
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.
@@ -258,7 +264,7 @@ File pattern support is documented at https://docs.github.com/en/actions/learn-g
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 action log when saving the cache entries.
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:
@@ -272,17 +278,18 @@ Note that this setting will also prevent certain cache operations from running i
### Optimizing cache effectiveness
Cache storage space for GitHub actions is limited, and writing new cache entries can trigger the deletion of exising entries.
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 identical cache entries will be stored separately for different branches.
An exception to this is that cache entries for the default (`master`/`main`) branch can be read by actions invoked for other branches.
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 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.
@@ -361,3 +368,9 @@ jobs:
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, with some important limitations:
- Support for GitHub Actions cache was introduced in GHES v3.5. Workflows using `gradle-build-action` on an earlier version of GHES will not benefit from save/restore of Gradle User Home.
- 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.

420
dist/main/index.js vendored
View File

@@ -90,18 +90,19 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
checkKey(key);
}
const compressionMethod = yield utils.getCompressionMethod();
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
const restoredEntry = new CacheEntry(cacheEntry.cacheKey);
let archivePath = '';
try {
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
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()) {
@@ -112,6 +113,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully');
return restoredEntry;
}
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}`);
}
}
finally {
// Try to delete the archive to save space
@@ -122,7 +134,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`);
}
}
return restoredEntry;
return undefined;
});
}
exports.restoreCache = restoreCache;
@@ -140,7 +152,7 @@ function saveCache(paths, key, options) {
checkPaths(paths);
checkKey(key);
const compressionMethod = yield utils.getCompressionMethod();
let cacheId = null;
let cacheId = -1;
const cachePaths = yield utils.resolvePaths(paths);
core.debug('Cache Paths:');
core.debug(`${JSON.stringify(cachePaths)}`);
@@ -181,6 +193,18 @@ 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 {
@@ -2732,6 +2756,13 @@ Object.defineProperty(exports, "summary", ({ enumerable: true, get: function ()
*/
var summary_2 = __nccwpck_require__(1327);
Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } }));
/**
* Path exports
*/
var path_utils_1 = __nccwpck_require__(2981);
Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } }));
Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } }));
Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } }));
//# sourceMappingURL=core.js.map
/***/ }),
@@ -2869,6 +2900,71 @@ exports.OidcClient = OidcClient;
/***/ }),
/***/ 2981:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0;
const path = __importStar(__nccwpck_require__(1017));
/**
* toPosixPath converts the given path to the posix form. On Windows, \\ will be
* replaced with /.
*
* @param pth. Path to transform.
* @return string Posix path.
*/
function toPosixPath(pth) {
return pth.replace(/[\\]/g, '/');
}
exports.toPosixPath = toPosixPath;
/**
* toWin32Path converts the given path to the win32 form. On Linux, / will be
* replaced with \\.
*
* @param pth. Path to transform.
* @return string Win32 path.
*/
function toWin32Path(pth) {
return pth.replace(/[/]/g, '\\');
}
exports.toWin32Path = toWin32Path;
/**
* toPlatformPath converts the given path to a platform-specific path. It does
* this by replacing instances of / and \ with the platform-specific path
* separator.
*
* @param pth The path to platformize.
* @return string The platform-specific path.
*/
function toPlatformPath(pth) {
return pth.replace(/[/\\]/g, path.sep);
}
exports.toPlatformPath = toPlatformPath;
//# sourceMappingURL=path-utils.js.map
/***/ }),
/***/ 1327:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@@ -64802,6 +64898,54 @@ function wrappy (fn, cb) {
}).call(this);
/***/ }),
/***/ 3017:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.loadBuildResults = void 0;
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
function loadBuildResults() {
const buildResultsDir = path.resolve(process.env['RUNNER_TEMP'], '.build-results');
if (!fs.existsSync(buildResultsDir)) {
return [];
}
return fs.readdirSync(buildResultsDir).map(file => {
const filePath = path.join(buildResultsDir, file);
const content = fs.readFileSync(filePath, 'utf8');
return JSON.parse(content);
});
}
exports.loadBuildResults = loadBuildResults;
/***/ }),
/***/ 7591:
@@ -65061,7 +65205,7 @@ const core = __importStar(__nccwpck_require__(2186));
const glob = __importStar(__nccwpck_require__(8090));
const cache_base_1 = __nccwpck_require__(7591);
const cache_utils_1 = __nccwpck_require__(1678);
const job_summary_1 = __nccwpck_require__(7345);
const build_results_1 = __nccwpck_require__(3017);
const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE';
class ExtractedCacheEntry {
constructor(artifactType, pattern, cacheKey) {
@@ -65294,7 +65438,7 @@ class ConfigurationCacheEntryExtractor extends AbstractEntryExtractor {
});
}
getProjectRoots() {
const buildResults = (0, job_summary_1.loadBuildResults)();
const buildResults = (0, build_results_1.loadBuildResults)();
const projectRootDirs = buildResults.map(x => x.rootProjectDir);
return [...new Set(projectRootDirs)];
}
@@ -65333,24 +65477,27 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.logCachingReport = exports.CacheEntryListener = exports.CacheListener = void 0;
exports.logCachingReport = exports.writeCachingReport = exports.CacheEntryListener = exports.CacheListener = void 0;
const core = __importStar(__nccwpck_require__(2186));
const cache = __importStar(__nccwpck_require__(7799));
class CacheListener {
constructor() {
this.cacheEntries = [];
this.isCacheReadOnly = false;
this.isCacheWriteOnly = false;
this.isCacheDisabled = false;
this.cacheReadOnly = false;
this.cacheWriteOnly = false;
this.cacheDisabled = false;
}
get fullyRestored() {
return this.cacheEntries.every(x => !x.wasRequestedButNotRestored());
}
get cacheStatus() {
if (this.isCacheDisabled)
if (!cache.isFeatureAvailable())
return 'not available';
if (this.cacheDisabled)
return 'disabled';
if (this.isCacheWriteOnly)
if (this.cacheWriteOnly)
return 'write-only';
if (this.isCacheReadOnly)
if (this.cacheReadOnly)
return 'read-only';
return 'enabled';
}
@@ -65414,7 +65561,7 @@ class CacheEntryListener {
}
}
exports.CacheEntryListener = CacheEntryListener;
function logCachingReport(listener) {
function writeCachingReport(listener) {
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([
@@ -65427,29 +65574,42 @@ function logCachingReport(listener) {
['Entries Saved', `${getCount(entries, e => e.savedSize)}`, `${getSize(entries, e => e.savedSize)}`]
]);
core.summary.addHeading('Cache Entry Details', 5);
const entryDetails = listener.cacheEntries
.map(entry => {
var _a, _b, _c;
return `Entry: ${entry.entryName}
Requested Key : ${(_a = entry.requestedKey) !== null && _a !== void 0 ? _a : ''}
Restored Key : ${(_b = entry.restoredKey) !== null && _b !== void 0 ? _b : ''}
Size: ${formatSize(entry.restoredSize)}
${getRestoredMessage(entry, listener.isCacheWriteOnly)}
Saved Key : ${(_c = entry.savedKey) !== null && _c !== void 0 ? _c : ''}
Size: ${formatSize(entry.savedSize)}
${getSavedMessage(entry, listener.isCacheReadOnly)}
`;
})
.join('---\n');
const entryDetails = renderEntryDetails(listener);
core.summary.addRaw(`<pre>
${entryDetails}
</pre>
</details>
`);
}
exports.writeCachingReport = writeCachingReport;
function logCachingReport(listener) {
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();
}
exports.logCachingReport = logCachingReport;
function getRestoredMessage(entry, isCacheWriteOnly) {
if (isCacheWriteOnly) {
function renderEntryDetails(listener) {
return listener.cacheEntries
.map(entry => {
var _a, _b, _c;
return `Entry: ${entry.entryName}
Requested Key : ${(_a = entry.requestedKey) !== null && _a !== void 0 ? _a : ''}
Restored Key : ${(_b = entry.restoredKey) !== null && _b !== void 0 ? _b : ''}
Size: ${formatSize(entry.restoredSize)}
${getRestoredMessage(entry, listener.cacheWriteOnly)}
Saved Key : ${(_c = entry.savedKey) !== null && _c !== void 0 ? _c : ''}
Size: ${formatSize(entry.savedSize)}
${getSavedMessage(entry, listener.cacheReadOnly)}
`;
})
.join('---\n');
}
function getRestoredMessage(entry, cacheWriteOnly) {
if (cacheWriteOnly) {
return '(Entry not restored: cache is write-only)';
}
if (entry.restoredKey === undefined) {
@@ -65460,12 +65620,12 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
}
return '(Entry restored: partial match found)';
}
function getSavedMessage(entry, isCacheReadOnly) {
function getSavedMessage(entry, cacheReadOnly) {
if (entry.unsaved) {
return `(Entry not saved: ${entry.unsaved})`;
}
if (entry.savedKey === undefined) {
if (isCacheReadOnly) {
if (cacheReadOnly) {
return '(Entry not saved: cache is read-only)';
}
return '(Entry not saved: reason unknown)';
@@ -65551,6 +65711,9 @@ 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';
function isCacheDisabled() {
if (!cache.isFeatureAvailable()) {
return true;
}
return core.getBooleanInput(CACHE_DISABLED_PARAMETER);
}
exports.isCacheDisabled = isCacheDisabled;
@@ -65777,7 +65940,7 @@ function restore(gradleUserHome, cacheListener) {
if ((0, cache_utils_1.isCacheDisabled)()) {
core.info('Cache is disabled: will not restore state from previous builds.');
gradleStateCache.init();
cacheListener.isCacheDisabled = true;
cacheListener.cacheDisabled = true;
return;
}
if (gradleStateCache.cacheOutputExists()) {
@@ -65789,7 +65952,7 @@ function restore(gradleUserHome, cacheListener) {
core.saveState(CACHE_RESTORED_VAR, true);
if ((0, cache_utils_1.isCacheWriteOnly)()) {
core.info('Cache is write-only: will not restore from cache.');
cacheListener.isCacheWriteOnly = true;
cacheListener.cacheWriteOnly = true;
return;
}
yield core.group('Restore Gradle state from cache', () => __awaiter(this, void 0, void 0, function* () {
@@ -65798,33 +65961,101 @@ function restore(gradleUserHome, cacheListener) {
});
}
exports.restore = restore;
function save(gradleUserHome, cacheListener) {
function save(gradleUserHome, cacheListener, daemonController) {
return __awaiter(this, void 0, void 0, function* () {
if (!shouldSaveCaches()) {
if ((0, cache_utils_1.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 ((0, cache_utils_1.isCacheReadOnly)()) {
core.info('Cache is read-only: will not save state for use in subsequent builds.');
cacheListener.isCacheReadOnly = true;
cacheListener.cacheReadOnly = true;
return;
}
yield daemonController.stopAllDaemons();
yield core.group('Caching Gradle state', () => __awaiter(this, void 0, void 0, function* () {
return new cache_base_1.GradleStateCache(gradleUserHome).save(cacheListener);
}));
});
}
exports.save = save;
function shouldSaveCaches() {
if ((0, cache_utils_1.isCacheDisabled)()) {
core.info('Cache is disabled: will not save state for later builds.');
return false;
/***/ }),
/***/ 5146:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
if (!core.getState(CACHE_RESTORED_VAR)) {
core.info('Cache will not be saved: not restored in main action step.');
return false;
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DaemonController = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
class DaemonController {
constructor(buildResults) {
const allHomes = buildResults.map(buildResult => buildResult.gradleHomeDir);
this.gradleHomes = Array.from(new Set(allHomes));
}
stopAllDaemons() {
return __awaiter(this, void 0, void 0, function* () {
core.info('Stopping all Gradle daemons before saving Gradle User Home state');
const executions = [];
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
}));
}
yield Promise.all(executions);
});
}
return true;
}
exports.DaemonController = DaemonController;
/***/ }),
@@ -65997,14 +66228,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.loadBuildResults = exports.writeJobSummary = void 0;
exports.logJobSummary = exports.writeJobSummary = void 0;
const core = __importStar(__nccwpck_require__(2186));
const fs_1 = __importDefault(__nccwpck_require__(7147));
const path_1 = __importDefault(__nccwpck_require__(1017));
const cache_reporting_1 = __nccwpck_require__(6674);
function writeJobSummary(buildResults, cacheListener) {
return __awaiter(this, void 0, void 0, function* () {
@@ -66015,23 +66241,23 @@ function writeJobSummary(buildResults, cacheListener) {
else {
writeSummaryTable(buildResults);
}
(0, cache_reporting_1.logCachingReport)(cacheListener);
(0, cache_reporting_1.writeCachingReport)(cacheListener);
yield core.summary.write();
});
}
exports.writeJobSummary = writeJobSummary;
function loadBuildResults() {
const buildResultsDir = path_1.default.resolve(process.env['RUNNER_TEMP'], '.build-results');
if (!fs_1.default.existsSync(buildResultsDir)) {
return [];
}
return fs_1.default.readdirSync(buildResultsDir).map(file => {
const filePath = path_1.default.join(buildResultsDir, file);
const content = fs_1.default.readFileSync(filePath, 'utf8');
return JSON.parse(content);
function logJobSummary(buildResults, cacheListener) {
return __awaiter(this, void 0, void 0, function* () {
if (buildResults.length === 0) {
core.debug('No Gradle build results found. Summary table will not be logged.');
}
else {
logSummaryTable(buildResults);
}
(0, cache_reporting_1.logCachingReport)(cacheListener);
});
}
exports.loadBuildResults = loadBuildResults;
exports.logJobSummary = logJobSummary;
function writeSummaryTable(results) {
core.summary.addHeading('Gradle Builds', 3);
core.summary.addRaw(`
@@ -66073,6 +66299,17 @@ function renderBuildScanBadge(outcomeText, outcomeColor, targetUrl) {
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`;
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
}
function logSummaryTable(results) {
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('============================');
}
/***/ }),
@@ -66419,12 +66656,13 @@ exports.complete = exports.setup = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const summary_1 = __nccwpck_require__(1327);
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
const os = __importStar(__nccwpck_require__(2037));
const caches = __importStar(__nccwpck_require__(3800));
const cache_reporting_1 = __nccwpck_require__(6674);
const job_summary_1 = __nccwpck_require__(7345);
const build_results_1 = __nccwpck_require__(3017);
const cache_reporting_1 = __nccwpck_require__(6674);
const daemon_controller_1 = __nccwpck_require__(5146);
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED';
const GRADLE_USER_HOME = 'GRADLE_USER_HOME';
const CACHE_LISTENER = 'CACHE_LISTENER';
@@ -66457,15 +66695,17 @@ function complete() {
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
return;
}
const buildResults = (0, job_summary_1.loadBuildResults)();
core.info('Stopping all Gradle daemons');
yield stopAllDaemons(getUniqueGradleHomes(buildResults));
core.info('In final post-action step, saving state and writing summary');
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
const buildResults = (0, build_results_1.loadBuildResults)();
const gradleUserHome = core.getState(GRADLE_USER_HOME);
yield caches.save(gradleUserHome, cacheListener);
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
const daemonController = new daemon_controller_1.DaemonController(buildResults);
yield caches.save(gradleUserHome, cacheListener, daemonController);
if (shouldGenerateJobSummary()) {
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
yield (0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
}
else {
(0, job_summary_1.logJobSummary)(buildResults, cacheListener);
}
});
}
@@ -66493,28 +66733,6 @@ function determineUserHome() {
return userHome;
});
}
function getUniqueGradleHomes(buildResults) {
const gradleHomes = buildResults.map(buildResult => buildResult.gradleHomeDir);
return Array.from(new Set(gradleHomes));
}
function stopAllDaemons(gradleHomes) {
return __awaiter(this, void 0, void 0, function* () {
const executions = [];
const args = ['--stop'];
for (const gradleHome of 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 in ${gradleHome}`);
executions.push(exec.exec(executable, args, {
ignoreReturnCode: true
}));
}
yield Promise.all(executions);
});
}
/***/ }),

File diff suppressed because one or more lines are too long

420
dist/post/index.js vendored
View File

@@ -90,18 +90,19 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
checkKey(key);
}
const compressionMethod = yield utils.getCompressionMethod();
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
const restoredEntry = new CacheEntry(cacheEntry.cacheKey);
let archivePath = '';
try {
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
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()) {
@@ -112,6 +113,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully');
return restoredEntry;
}
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}`);
}
}
finally {
// Try to delete the archive to save space
@@ -122,7 +134,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`);
}
}
return restoredEntry;
return undefined;
});
}
exports.restoreCache = restoreCache;
@@ -140,7 +152,7 @@ function saveCache(paths, key, options) {
checkPaths(paths);
checkKey(key);
const compressionMethod = yield utils.getCompressionMethod();
let cacheId = null;
let cacheId = -1;
const cachePaths = yield utils.resolvePaths(paths);
core.debug('Cache Paths:');
core.debug(`${JSON.stringify(cachePaths)}`);
@@ -181,6 +193,18 @@ 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 {
@@ -2732,6 +2756,13 @@ Object.defineProperty(exports, "summary", ({ enumerable: true, get: function ()
*/
var summary_2 = __nccwpck_require__(1327);
Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } }));
/**
* Path exports
*/
var path_utils_1 = __nccwpck_require__(2981);
Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } }));
Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } }));
Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } }));
//# sourceMappingURL=core.js.map
/***/ }),
@@ -2869,6 +2900,71 @@ exports.OidcClient = OidcClient;
/***/ }),
/***/ 2981:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0;
const path = __importStar(__nccwpck_require__(1017));
/**
* toPosixPath converts the given path to the posix form. On Windows, \\ will be
* replaced with /.
*
* @param pth. Path to transform.
* @return string Posix path.
*/
function toPosixPath(pth) {
return pth.replace(/[\\]/g, '/');
}
exports.toPosixPath = toPosixPath;
/**
* toWin32Path converts the given path to the win32 form. On Linux, / will be
* replaced with \\.
*
* @param pth. Path to transform.
* @return string Win32 path.
*/
function toWin32Path(pth) {
return pth.replace(/[/]/g, '\\');
}
exports.toWin32Path = toWin32Path;
/**
* toPlatformPath converts the given path to a platform-specific path. It does
* this by replacing instances of / and \ with the platform-specific path
* separator.
*
* @param pth The path to platformize.
* @return string The platform-specific path.
*/
function toPlatformPath(pth) {
return pth.replace(/[/\\]/g, path.sep);
}
exports.toPlatformPath = toPlatformPath;
//# sourceMappingURL=path-utils.js.map
/***/ }),
/***/ 1327:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@@ -63853,6 +63949,54 @@ function wrappy (fn, cb) {
}).call(this);
/***/ }),
/***/ 3017:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.loadBuildResults = void 0;
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
function loadBuildResults() {
const buildResultsDir = path.resolve(process.env['RUNNER_TEMP'], '.build-results');
if (!fs.existsSync(buildResultsDir)) {
return [];
}
return fs.readdirSync(buildResultsDir).map(file => {
const filePath = path.join(buildResultsDir, file);
const content = fs.readFileSync(filePath, 'utf8');
return JSON.parse(content);
});
}
exports.loadBuildResults = loadBuildResults;
/***/ }),
/***/ 7591:
@@ -64112,7 +64256,7 @@ const core = __importStar(__nccwpck_require__(2186));
const glob = __importStar(__nccwpck_require__(8090));
const cache_base_1 = __nccwpck_require__(7591);
const cache_utils_1 = __nccwpck_require__(1678);
const job_summary_1 = __nccwpck_require__(7345);
const build_results_1 = __nccwpck_require__(3017);
const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE';
class ExtractedCacheEntry {
constructor(artifactType, pattern, cacheKey) {
@@ -64345,7 +64489,7 @@ class ConfigurationCacheEntryExtractor extends AbstractEntryExtractor {
});
}
getProjectRoots() {
const buildResults = (0, job_summary_1.loadBuildResults)();
const buildResults = (0, build_results_1.loadBuildResults)();
const projectRootDirs = buildResults.map(x => x.rootProjectDir);
return [...new Set(projectRootDirs)];
}
@@ -64384,24 +64528,27 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.logCachingReport = exports.CacheEntryListener = exports.CacheListener = void 0;
exports.logCachingReport = exports.writeCachingReport = exports.CacheEntryListener = exports.CacheListener = void 0;
const core = __importStar(__nccwpck_require__(2186));
const cache = __importStar(__nccwpck_require__(7799));
class CacheListener {
constructor() {
this.cacheEntries = [];
this.isCacheReadOnly = false;
this.isCacheWriteOnly = false;
this.isCacheDisabled = false;
this.cacheReadOnly = false;
this.cacheWriteOnly = false;
this.cacheDisabled = false;
}
get fullyRestored() {
return this.cacheEntries.every(x => !x.wasRequestedButNotRestored());
}
get cacheStatus() {
if (this.isCacheDisabled)
if (!cache.isFeatureAvailable())
return 'not available';
if (this.cacheDisabled)
return 'disabled';
if (this.isCacheWriteOnly)
if (this.cacheWriteOnly)
return 'write-only';
if (this.isCacheReadOnly)
if (this.cacheReadOnly)
return 'read-only';
return 'enabled';
}
@@ -64465,7 +64612,7 @@ class CacheEntryListener {
}
}
exports.CacheEntryListener = CacheEntryListener;
function logCachingReport(listener) {
function writeCachingReport(listener) {
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([
@@ -64478,29 +64625,42 @@ function logCachingReport(listener) {
['Entries Saved', `${getCount(entries, e => e.savedSize)}`, `${getSize(entries, e => e.savedSize)}`]
]);
core.summary.addHeading('Cache Entry Details', 5);
const entryDetails = listener.cacheEntries
.map(entry => {
var _a, _b, _c;
return `Entry: ${entry.entryName}
Requested Key : ${(_a = entry.requestedKey) !== null && _a !== void 0 ? _a : ''}
Restored Key : ${(_b = entry.restoredKey) !== null && _b !== void 0 ? _b : ''}
Size: ${formatSize(entry.restoredSize)}
${getRestoredMessage(entry, listener.isCacheWriteOnly)}
Saved Key : ${(_c = entry.savedKey) !== null && _c !== void 0 ? _c : ''}
Size: ${formatSize(entry.savedSize)}
${getSavedMessage(entry, listener.isCacheReadOnly)}
`;
})
.join('---\n');
const entryDetails = renderEntryDetails(listener);
core.summary.addRaw(`<pre>
${entryDetails}
</pre>
</details>
`);
}
exports.writeCachingReport = writeCachingReport;
function logCachingReport(listener) {
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();
}
exports.logCachingReport = logCachingReport;
function getRestoredMessage(entry, isCacheWriteOnly) {
if (isCacheWriteOnly) {
function renderEntryDetails(listener) {
return listener.cacheEntries
.map(entry => {
var _a, _b, _c;
return `Entry: ${entry.entryName}
Requested Key : ${(_a = entry.requestedKey) !== null && _a !== void 0 ? _a : ''}
Restored Key : ${(_b = entry.restoredKey) !== null && _b !== void 0 ? _b : ''}
Size: ${formatSize(entry.restoredSize)}
${getRestoredMessage(entry, listener.cacheWriteOnly)}
Saved Key : ${(_c = entry.savedKey) !== null && _c !== void 0 ? _c : ''}
Size: ${formatSize(entry.savedSize)}
${getSavedMessage(entry, listener.cacheReadOnly)}
`;
})
.join('---\n');
}
function getRestoredMessage(entry, cacheWriteOnly) {
if (cacheWriteOnly) {
return '(Entry not restored: cache is write-only)';
}
if (entry.restoredKey === undefined) {
@@ -64511,12 +64671,12 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
}
return '(Entry restored: partial match found)';
}
function getSavedMessage(entry, isCacheReadOnly) {
function getSavedMessage(entry, cacheReadOnly) {
if (entry.unsaved) {
return `(Entry not saved: ${entry.unsaved})`;
}
if (entry.savedKey === undefined) {
if (isCacheReadOnly) {
if (cacheReadOnly) {
return '(Entry not saved: cache is read-only)';
}
return '(Entry not saved: reason unknown)';
@@ -64602,6 +64762,9 @@ 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';
function isCacheDisabled() {
if (!cache.isFeatureAvailable()) {
return true;
}
return core.getBooleanInput(CACHE_DISABLED_PARAMETER);
}
exports.isCacheDisabled = isCacheDisabled;
@@ -64828,7 +64991,7 @@ function restore(gradleUserHome, cacheListener) {
if ((0, cache_utils_1.isCacheDisabled)()) {
core.info('Cache is disabled: will not restore state from previous builds.');
gradleStateCache.init();
cacheListener.isCacheDisabled = true;
cacheListener.cacheDisabled = true;
return;
}
if (gradleStateCache.cacheOutputExists()) {
@@ -64840,7 +65003,7 @@ function restore(gradleUserHome, cacheListener) {
core.saveState(CACHE_RESTORED_VAR, true);
if ((0, cache_utils_1.isCacheWriteOnly)()) {
core.info('Cache is write-only: will not restore from cache.');
cacheListener.isCacheWriteOnly = true;
cacheListener.cacheWriteOnly = true;
return;
}
yield core.group('Restore Gradle state from cache', () => __awaiter(this, void 0, void 0, function* () {
@@ -64849,33 +65012,101 @@ function restore(gradleUserHome, cacheListener) {
});
}
exports.restore = restore;
function save(gradleUserHome, cacheListener) {
function save(gradleUserHome, cacheListener, daemonController) {
return __awaiter(this, void 0, void 0, function* () {
if (!shouldSaveCaches()) {
if ((0, cache_utils_1.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 ((0, cache_utils_1.isCacheReadOnly)()) {
core.info('Cache is read-only: will not save state for use in subsequent builds.');
cacheListener.isCacheReadOnly = true;
cacheListener.cacheReadOnly = true;
return;
}
yield daemonController.stopAllDaemons();
yield core.group('Caching Gradle state', () => __awaiter(this, void 0, void 0, function* () {
return new cache_base_1.GradleStateCache(gradleUserHome).save(cacheListener);
}));
});
}
exports.save = save;
function shouldSaveCaches() {
if ((0, cache_utils_1.isCacheDisabled)()) {
core.info('Cache is disabled: will not save state for later builds.');
return false;
/***/ }),
/***/ 5146:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
if (!core.getState(CACHE_RESTORED_VAR)) {
core.info('Cache will not be saved: not restored in main action step.');
return false;
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DaemonController = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
class DaemonController {
constructor(buildResults) {
const allHomes = buildResults.map(buildResult => buildResult.gradleHomeDir);
this.gradleHomes = Array.from(new Set(allHomes));
}
stopAllDaemons() {
return __awaiter(this, void 0, void 0, function* () {
core.info('Stopping all Gradle daemons before saving Gradle User Home state');
const executions = [];
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
}));
}
yield Promise.all(executions);
});
}
return true;
}
exports.DaemonController = DaemonController;
/***/ }),
@@ -64917,14 +65148,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.loadBuildResults = exports.writeJobSummary = void 0;
exports.logJobSummary = exports.writeJobSummary = void 0;
const core = __importStar(__nccwpck_require__(2186));
const fs_1 = __importDefault(__nccwpck_require__(7147));
const path_1 = __importDefault(__nccwpck_require__(1017));
const cache_reporting_1 = __nccwpck_require__(6674);
function writeJobSummary(buildResults, cacheListener) {
return __awaiter(this, void 0, void 0, function* () {
@@ -64935,23 +65161,23 @@ function writeJobSummary(buildResults, cacheListener) {
else {
writeSummaryTable(buildResults);
}
(0, cache_reporting_1.logCachingReport)(cacheListener);
(0, cache_reporting_1.writeCachingReport)(cacheListener);
yield core.summary.write();
});
}
exports.writeJobSummary = writeJobSummary;
function loadBuildResults() {
const buildResultsDir = path_1.default.resolve(process.env['RUNNER_TEMP'], '.build-results');
if (!fs_1.default.existsSync(buildResultsDir)) {
return [];
}
return fs_1.default.readdirSync(buildResultsDir).map(file => {
const filePath = path_1.default.join(buildResultsDir, file);
const content = fs_1.default.readFileSync(filePath, 'utf8');
return JSON.parse(content);
function logJobSummary(buildResults, cacheListener) {
return __awaiter(this, void 0, void 0, function* () {
if (buildResults.length === 0) {
core.debug('No Gradle build results found. Summary table will not be logged.');
}
else {
logSummaryTable(buildResults);
}
(0, cache_reporting_1.logCachingReport)(cacheListener);
});
}
exports.loadBuildResults = loadBuildResults;
exports.logJobSummary = logJobSummary;
function writeSummaryTable(results) {
core.summary.addHeading('Gradle Builds', 3);
core.summary.addRaw(`
@@ -64993,6 +65219,17 @@ function renderBuildScanBadge(outcomeText, outcomeColor, targetUrl) {
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`;
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
}
function logSummaryTable(results) {
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('============================');
}
/***/ }),
@@ -65103,12 +65340,13 @@ exports.complete = exports.setup = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const summary_1 = __nccwpck_require__(1327);
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
const os = __importStar(__nccwpck_require__(2037));
const caches = __importStar(__nccwpck_require__(3800));
const cache_reporting_1 = __nccwpck_require__(6674);
const job_summary_1 = __nccwpck_require__(7345);
const build_results_1 = __nccwpck_require__(3017);
const cache_reporting_1 = __nccwpck_require__(6674);
const daemon_controller_1 = __nccwpck_require__(5146);
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED';
const GRADLE_USER_HOME = 'GRADLE_USER_HOME';
const CACHE_LISTENER = 'CACHE_LISTENER';
@@ -65141,15 +65379,17 @@ function complete() {
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.');
return;
}
const buildResults = (0, job_summary_1.loadBuildResults)();
core.info('Stopping all Gradle daemons');
yield stopAllDaemons(getUniqueGradleHomes(buildResults));
core.info('In final post-action step, saving state and writing summary');
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
const buildResults = (0, build_results_1.loadBuildResults)();
const gradleUserHome = core.getState(GRADLE_USER_HOME);
yield caches.save(gradleUserHome, cacheListener);
const cacheListener = cache_reporting_1.CacheListener.rehydrate(core.getState(CACHE_LISTENER));
const daemonController = new daemon_controller_1.DaemonController(buildResults);
yield caches.save(gradleUserHome, cacheListener, daemonController);
if (shouldGenerateJobSummary()) {
(0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
yield (0, job_summary_1.writeJobSummary)(buildResults, cacheListener);
}
else {
(0, job_summary_1.logJobSummary)(buildResults, cacheListener);
}
});
}
@@ -65177,28 +65417,6 @@ function determineUserHome() {
return userHome;
});
}
function getUniqueGradleHomes(buildResults) {
const gradleHomes = buildResults.map(buildResult => buildResult.gradleHomeDir);
return Array.from(new Set(gradleHomes));
}
function stopAllDaemons(gradleHomes) {
return __awaiter(this, void 0, void 0, function* () {
const executions = [];
const args = ['--stop'];
for (const gradleHome of 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 in ${gradleHome}`);
executions.push(exec.exec(executable, args, {
ignoreReturnCode: true
}));
}
yield Promise.all(executions);
});
}
/***/ }),

File diff suppressed because one or more lines are too long

1592
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,8 +25,8 @@
],
"license": "MIT",
"dependencies": {
"@actions/cache": "2.0.6",
"@actions/core": "1.8.2",
"@actions/cache": "3.0.0",
"@actions/core": "1.9.0",
"@actions/exec": "1.1.1",
"@actions/github": "5.0.3",
"@actions/glob": "0.3.0",
@@ -35,19 +35,19 @@
"string-argv": "0.3.1"
},
"devDependencies": {
"@types/jest": "28.1.1",
"@types/jest": "28.1.4",
"@types/node": "16.11.21",
"@types/unzipper": "0.10.5",
"@typescript-eslint/parser": "5.28.0",
"@typescript-eslint/parser": "5.30.6",
"@vercel/ncc": "0.34.0",
"eslint": "8.17.0",
"eslint": "8.19.0",
"eslint-plugin-github": "4.3.6",
"eslint-plugin-jest": "26.5.3",
"jest": "28.1.1",
"jest": "28.1.2",
"js-yaml": "4.1.0",
"patch-package": "6.4.7",
"prettier": "2.7.0",
"prettier": "2.7.1",
"ts-jest": "28.0.5",
"typescript": "4.7.3"
"typescript": "4.7.4"
}
}

View File

@@ -26,18 +26,17 @@ index 16b20f7..aea77ba 100644
+ constructor(key: string, size?: number);
+}
diff --git a/node_modules/@actions/cache/lib/cache.js b/node_modules/@actions/cache/lib/cache.js
index 2dd645a..a392352 100644
index 4dc5e88..2141dd5 100644
--- a/node_modules/@actions/cache/lib/cache.js
+++ b/node_modules/@actions/cache/lib/cache.js
@@ -93,6 +93,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
+ const restoredEntry = new CacheEntry(cacheEntry.cacheKey);
try {
@@ -95,16 +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);
@@ -100,6 +101,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
if (core.isDebug()) {
yield tar_1.listTar(archivePath, compressionMethod);
}
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
@@ -45,16 +44,12 @@ index 2dd645a..a392352 100644
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully');
@@ -113,7 +115,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`);
}
- return cacheEntry.cacheKey;
+ return restoredEntry;
}
- return cacheEntry.cacheKey;
+ return restoredEntry;
});
}
exports.restoreCache = restoreCache;
@@ -141,6 +143,7 @@ function saveCache(paths, key, options) {
catch (error) {
const typedError = error;
@@ -153,6 +155,7 @@ function saveCache(paths, key, options) {
const archiveFolder = yield utils.createTempDirectory();
const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
@@ -62,7 +57,7 @@ index 2dd645a..a392352 100644
try {
yield tar_1.createTar(archiveFolder, cachePaths, compressionMethod);
if (core.isDebug()) {
@@ -148,6 +151,7 @@ function saveCache(paths, key, options) {
@@ -160,6 +163,7 @@ function saveCache(paths, key, options) {
}
const fileSizeLimit = 10 * 1024 * 1024 * 1024; // 10GB per repo limit
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
@@ -70,7 +65,7 @@ index 2dd645a..a392352 100644
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()) {
@@ -179,8 +183,15 @@ function saveCache(paths, key, options) {
@@ -203,8 +207,15 @@ function saveCache(paths, key, options) {
core.debug(`Failed to delete archive: ${error}`);
}
}

View File

@@ -1 +0,0 @@
- [NEW] Use Job Summary to display build scan links, instead of GHA annotations

27
src/build-results.ts Normal file
View 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
})
}

View File

@@ -14,7 +14,7 @@ import {
saveCache,
tryDelete
} from './cache-utils'
import {loadBuildResults} from './job-summary'
import {loadBuildResults} from './build-results'
const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE'

View File

@@ -1,4 +1,5 @@
import * as core from '@actions/core'
import * as cache from '@actions/cache'
/**
* Collects information on what entries were saved and restored during the action.
@@ -6,18 +7,19 @@ import * as core from '@actions/core'
*/
export class CacheListener {
cacheEntries: CacheEntryListener[] = []
isCacheReadOnly = false
isCacheWriteOnly = false
isCacheDisabled = false
cacheReadOnly = false
cacheWriteOnly = false
cacheDisabled = false
get fullyRestored(): boolean {
return this.cacheEntries.every(x => !x.wasRequestedButNotRestored())
}
get cacheStatus(): string {
if (this.isCacheDisabled) return 'disabled'
if (this.isCacheWriteOnly) return 'write-only'
if (this.isCacheReadOnly) return 'read-only'
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'
}
@@ -104,7 +106,7 @@ export class CacheEntryListener {
}
}
export function logCachingReport(listener: CacheListener): void {
export function writeCachingReport(listener: CacheListener): void {
const entries = listener.cacheEntries
core.summary.addRaw(
@@ -123,21 +125,7 @@ export function logCachingReport(listener: CacheListener): void {
core.summary.addHeading('Cache Entry Details', 5)
const entryDetails = listener.cacheEntries
.map(
entry =>
`Entry: ${entry.entryName}
Requested Key : ${entry.requestedKey ?? ''}
Restored Key : ${entry.restoredKey ?? ''}
Size: ${formatSize(entry.restoredSize)}
${getRestoredMessage(entry, listener.isCacheWriteOnly)}
Saved Key : ${entry.savedKey ?? ''}
Size: ${formatSize(entry.savedSize)}
${getSavedMessage(entry, listener.isCacheReadOnly)}
`
)
.join('---\n')
const entryDetails = renderEntryDetails(listener)
core.summary.addRaw(`<pre>
${entryDetails}
</pre>
@@ -145,8 +133,40 @@ ${entryDetails}
`)
}
function getRestoredMessage(entry: CacheEntryListener, isCacheWriteOnly: boolean): string {
if (isCacheWriteOnly) {
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 (cacheWriteOnly) {
return '(Entry not restored: cache is write-only)'
}
if (entry.restoredKey === undefined) {
@@ -158,12 +178,12 @@ function getRestoredMessage(entry: CacheEntryListener, isCacheWriteOnly: boolean
return '(Entry restored: partial match found)'
}
function getSavedMessage(entry: CacheEntryListener, isCacheReadOnly: boolean): string {
function getSavedMessage(entry: CacheEntryListener, cacheReadOnly: boolean): string {
if (entry.unsaved) {
return `(Entry not saved: ${entry.unsaved})`
}
if (entry.savedKey === undefined) {
if (isCacheReadOnly) {
if (cacheReadOnly) {
return '(Entry not saved: cache is read-only)'
}
return '(Entry not saved: reason unknown)'

View File

@@ -25,6 +25,9 @@ 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'
export function isCacheDisabled(): boolean {
if (!cache.isFeatureAvailable()) {
return true
}
return core.getBooleanInput(CACHE_DISABLED_PARAMETER)
}

View File

@@ -1,6 +1,7 @@
import * as core from '@actions/core'
import {isCacheDisabled, isCacheReadOnly, isCacheWriteOnly} from './cache-utils'
import {CacheListener} from './cache-reporting'
import {DaemonController} from './daemon-controller'
import {GradleStateCache} from './cache-base'
const CACHE_RESTORED_VAR = 'GRADLE_BUILD_ACTION_CACHE_RESTORED'
@@ -19,7 +20,7 @@ export async function restore(gradleUserHome: string, cacheListener: CacheListen
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.isCacheDisabled = true
cacheListener.cacheDisabled = true
return
}
@@ -36,7 +37,7 @@ export async function restore(gradleUserHome: string, cacheListener: CacheListen
if (isCacheWriteOnly()) {
core.info('Cache is write-only: will not restore from cache.')
cacheListener.isCacheWriteOnly = true
cacheListener.cacheWriteOnly = true
return
}
@@ -45,32 +46,30 @@ export async function restore(gradleUserHome: string, cacheListener: CacheListen
})
}
export async function save(gradleUserHome: string, cacheListener: CacheListener): Promise<void> {
if (!shouldSaveCaches()) {
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.isCacheReadOnly = true
cacheListener.cacheReadOnly = true
return
}
await daemonController.stopAllDaemons()
await core.group('Caching Gradle state', async () => {
return new GradleStateCache(gradleUserHome).save(cacheListener)
})
}
function shouldSaveCaches(): boolean {
if (isCacheDisabled()) {
core.info('Cache is disabled: will not save state for later builds.')
return false
}
if (!core.getState(CACHE_RESTORED_VAR)) {
core.info('Cache will not be saved: not restored in main action step.')
return false
}
return true
}

36
src/daemon-controller.ts Normal file
View 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)
}
}

View File

@@ -1,18 +1,6 @@
import * as core from '@actions/core'
import fs from 'fs'
import path from 'path'
import {logCachingReport, CacheListener} from './cache-reporting'
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
}
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')
@@ -23,23 +11,19 @@ export async function writeJobSummary(buildResults: BuildResult[], cacheListener
writeSummaryTable(buildResults)
}
logCachingReport(cacheListener)
writeCachingReport(cacheListener)
await core.summary.write()
}
export function loadBuildResults(): BuildResult[] {
const buildResultsDir = path.resolve(process.env['RUNNER_TEMP']!, '.build-results')
if (!fs.existsSync(buildResultsDir)) {
return []
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)
}
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
})
logCachingReport(cacheListener)
}
function writeSummaryTable(results: BuildResult[]): void {
@@ -92,3 +76,19 @@ function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetU
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('============================')
}

View File

@@ -45,9 +45,15 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
buildScanFailed: false
]
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
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, System.getenv("GITHUB_ACTION") + getParameters().getInvocationId().get() + ".json")
def buildResultsFile = new File(buildResultsDir, githubActionStep + getParameters().getInvocationId().get() + ".json")
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
}
}

View File

@@ -106,9 +106,15 @@ class BuildResults {
}
def writeToResultsFile(boolean overwrite) {
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
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, System.getenv("GITHUB_ACTION") + invocationId + ".json")
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()) {

View File

@@ -1,13 +1,14 @@
import * as core from '@actions/core'
import * as exec from '@actions/exec'
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
import * as fs from 'fs'
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 {BuildResult, loadBuildResults, writeJobSummary} from './job-summary'
import {DaemonController} from './daemon-controller'
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED'
const GRADLE_USER_HOME = 'GRADLE_USER_HOME'
@@ -50,20 +51,20 @@ export async function complete(): Promise<void> {
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()
core.info('Stopping all Gradle daemons')
await stopAllDaemons(getUniqueGradleHomes(buildResults))
core.info('In final post-action step, saving state and writing summary')
const cacheListener: CacheListener = CacheListener.rehydrate(core.getState(CACHE_LISTENER))
const gradleUserHome = core.getState(GRADLE_USER_HOME)
await caches.save(gradleUserHome, cacheListener)
const cacheListener: CacheListener = CacheListener.rehydrate(core.getState(CACHE_LISTENER))
const daemonController = new DaemonController(buildResults)
await caches.save(gradleUserHome, cacheListener, daemonController)
if (shouldGenerateJobSummary()) {
writeJobSummary(buildResults, cacheListener)
await writeJobSummary(buildResults, cacheListener)
} else {
logJobSummary(buildResults, cacheListener)
}
}
@@ -92,28 +93,3 @@ async function determineUserHome(): Promise<string> {
core.debug(`Determined user.home from java -version output: '${userHome}'`)
return userHome
}
function getUniqueGradleHomes(buildResults: BuildResult[]): string[] {
const gradleHomes = buildResults.map(buildResult => buildResult.gradleHomeDir)
return Array.from(new Set(gradleHomes))
}
async function stopAllDaemons(gradleHomes: string[]): Promise<void> {
const executions: Promise<number>[] = []
const args = ['--stop']
for (const gradleHome of 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 in ${gradleHome}`)
executions.push(
exec.exec(executable, args, {
ignoreReturnCode: true
})
)
}
await Promise.all(executions)
}

View File

@@ -200,20 +200,17 @@ task expectFailure {
File initScriptsDir = new File(testProjectDir, "initScripts")
args << '-I' << new File(initScriptsDir, initScript).absolutePath
envVars['RUNNER_TEMP'] = testProjectDir.absolutePath
envVars['GITHUB_ACTION'] = 'github-step-id'
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()
if (envVars) {
runner.withEnvironment(envVars)
}
runner
}

View File

@@ -134,6 +134,20 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
testGradleVersion << ALL_VERSIONS
}
def "produces no build results file when GitHub env vars not set with #testGradleVersion"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
run(['help'], initScript, testGradleVersion.gradleVersion, [], [RUNNER_TEMP: '', GITHUB_ACTION: ''])
then:
def buildResultsDir = new File(testProjectDir, '.build-results')
assert !buildResultsDir.exists()
where:
testGradleVersion << ALL_VERSIONS
}
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean hasBuildScan, boolean scanUploadFailed = false) {
def results = new JsonSlurper().parse(buildResultFile)
assert results['rootProjectName'] == ROOT_PROJECT_NAME