Compare commits

...

99 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
Daz DeBoer
67421db6bd Merge pull request #333 from gradle/dd/build-scan-failure
Report failure to publish build scan in Job Summary
2022-06-19 10:51:24 -06:00
Daz DeBoer
ce3874fec9 Build outputs 2022-06-19 10:43:31 -06:00
Daz DeBoer
67f42d16a1 Write Job Summary HTML directly
This allows more control over the table layout, including centering of column content.
2022-06-19 10:42:34 -06:00
Daz DeBoer
56036f8577 Improve rendering of Job Summary 2022-06-19 09:40:27 -06:00
Daz DeBoer
1903bd4674 Add test for build-scan publish failure 2022-06-19 09:16:27 -06:00
Daz DeBoer
df4c1902a6 Extract common functionality for recording build results 2022-06-15 08:29:55 -06:00
Daz DeBoer
132237ba05 Capture failure to publish build scan in results 2022-06-15 08:08:41 -06:00
Daz DeBoer
2335d51128 Add mandatory 'distribution' param for setup-java 2022-06-14 12:11:44 -06:00
Daz DeBoer
2f7e5c0d4b Merge pull request #332 from gradle/dependabot/npm_and_yarn/prettier-2.7.0
Bump prettier from 2.6.2 to 2.7.0
2022-06-14 11:54:58 -06:00
dependabot[bot]
2248b3f239 Bump prettier from 2.6.2 to 2.7.0
Bumps [prettier](https://github.com/prettier/prettier) from 2.6.2 to 2.7.0.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.6.2...2.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-14 17:30:47 +00:00
Daz DeBoer
7d8a9a65e5 Reduce NPM dependabot updates to weekly 2022-06-14 11:30:15 -06:00
Daz DeBoer
bc39e4abaa Merge pull request #329 from gradle/dependabot/npm_and_yarn/typescript-eslint/parser-5.28.0
Bump @typescript-eslint/parser from 5.27.1 to 5.28.0
2022-06-14 07:47:39 -06:00
Daz DeBoer
26cd1c9794 Merge pull request #328 from gradle/dependabot/npm_and_yarn/ts-jest-28.0.5
Bump ts-jest from 28.0.4 to 28.0.5
2022-06-14 07:47:27 -06:00
dependabot[bot]
5ccc7fa6a6 Bump @typescript-eslint/parser from 5.27.1 to 5.28.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.27.1 to 5.28.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.28.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-13 22:27:38 +00:00
dependabot[bot]
badf18c0a6 Bump ts-jest from 28.0.4 to 28.0.5
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 28.0.4 to 28.0.5.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kulshekhar/ts-jest/compare/v28.0.4...v28.0.5)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 22:27:19 +00:00
Daz DeBoer
1ee84620f9 Merge pull request #327 from gradle/dd/test-reorg
Consolidate all tests under 'test' directory
2022-06-13 15:53:41 -06:00
Daz DeBoer
f1c1269910 Build outputs 2022-06-12 09:55:45 -06:00
Daz DeBoer
c09f41c4bd Move Jest tests from '__tests__' to 'test/jest' 2022-06-11 09:39:59 -06:00
Daz DeBoer
829c7a236d Removed unused test resources 2022-06-11 09:33:39 -06:00
Daz DeBoer
c1ed8b1925 Only run ci-init-script-check on relevant file changes 2022-06-11 09:33:39 -06:00
Daz DeBoer
3d091fa7a8 Move initscripts into src/resources/init-scripts 2022-06-11 09:33:38 -06:00
Daz DeBoer
a8d44c9749 Rename 'test/test-init-script' to 'test/init-scripts' 2022-06-11 09:32:50 -06:00
Daz DeBoer
6125b490f2 Merge pull request #325 from gradle/dependabot/gradle/dot-github/workflow-samples/no-wrapper/com.gradle.enterprise-3.10.2
Bump com.gradle.enterprise from 3.10.1 to 3.10.2 in /.github/workflow-samples/no-wrapper
2022-06-09 22:30:09 -06:00
Daz DeBoer
f75a77b009 Merge pull request #324 from gradle/dependabot/gradle/dot-github/workflow-samples/kotlin-dsl/com.gradle.enterprise-3.10.2
Bump com.gradle.enterprise from 3.10.1 to 3.10.2 in /.github/workflow-samples/kotlin-dsl
2022-06-09 22:29:58 -06:00
Daz DeBoer
3510b43886 Merge pull request #322 from gradle/dependabot/gradle/dot-github/workflow-samples/no-wrapper-gradle-5/com.gradle.build-scan-3.10.2
Bump com.gradle.build-scan from 3.10.1 to 3.10.2 in /.github/workflow-samples/no-wrapper-gradle-5
2022-06-09 22:29:45 -06:00
Daz DeBoer
61ba2ad220 Merge pull request #323 from gradle/dependabot/gradle/dot-github/workflow-samples/groovy-dsl/com.gradle.enterprise-3.10.2
Bump com.gradle.enterprise from 3.10.1 to 3.10.2 in /.github/workflow-samples/groovy-dsl
2022-06-09 22:29:35 -06:00
dependabot[bot]
4b449e5b54 Bump com.gradle.enterprise in /.github/workflow-samples/no-wrapper
Bumps com.gradle.enterprise from 3.10.1 to 3.10.2.

---
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-06-09 22:40:35 +00:00
dependabot[bot]
b8f0ecc408 Bump com.gradle.enterprise in /.github/workflow-samples/groovy-dsl
Bumps com.gradle.enterprise from 3.10.1 to 3.10.2.

---
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-06-09 22:40:34 +00:00
dependabot[bot]
c2bd86551b Bump com.gradle.enterprise in /.github/workflow-samples/kotlin-dsl
Bumps com.gradle.enterprise from 3.10.1 to 3.10.2.

---
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-06-09 22:40:33 +00:00
dependabot[bot]
92087b6bb6 Bump com.gradle.build-scan
Bumps com.gradle.build-scan from 3.10.1 to 3.10.2.

---
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-06-09 22:40:33 +00:00
Daz DeBoer
9355458b6c Merge pull request #321 from gradle/dd/check-for-job-summary-support
Check that job summary support is available
2022-06-09 09:36:42 -06:00
Daz DeBoer
4ec1021d58 Merge pull request #315 from gradle/dependabot/npm_and_yarn/jest-28.1.1
Bump jest from 28.1.0 to 28.1.1
2022-06-09 09:36:25 -06:00
Daz DeBoer
f3e4903860 Check that job summary support is available
Fixes #319
2022-06-09 09:26:30 -06:00
dependabot[bot]
c5d80a628f Bump jest from 28.1.0 to 28.1.1
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 28.1.0 to 28.1.1.
- [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.1/packages/jest)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-07 22:17:49 +00:00
Daz DeBoer
ee54c1fd71 Bump @actions/cache from 2.0.5 to 2.0.6 2022-06-06 19:12:03 -06:00
Daz DeBoer
f33d84950e Run verify-outputs on every push to 'main' 2022-06-06 19:04:28 -06:00
Daz DeBoer
d20c5c0356 Merge pull request #314 from gradle/dependabot/npm_and_yarn/typescript-eslint/parser-5.27.1
Bump @typescript-eslint/parser from 5.27.0 to 5.27.1
2022-06-06 19:01:11 -06:00
Daz DeBoer
c207cf448f Merge pull request #312 from gradle/dependabot/npm_and_yarn/types/jest-28.1.1
Bump @types/jest from 28.1.0 to 28.1.1
2022-06-06 19:00:47 -06:00
Daz DeBoer
a534572737 Merge pull request #311 from gradle/dependabot/npm_and_yarn/eslint-plugin-jest-26.5.3
Bump eslint-plugin-jest from 26.4.6 to 26.5.3
2022-06-06 19:00:34 -06:00
dependabot[bot]
acf6027bd2 Bump @typescript-eslint/parser from 5.27.0 to 5.27.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.27.0 to 5.27.1.
- [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.27.1/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-06-06 22:20:14 +00:00
dependabot[bot]
f6ab09b0bf Bump @types/jest from 28.1.0 to 28.1.1
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 28.1.0 to 28.1.1.
- [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-06 22:19:41 +00:00
dependabot[bot]
55ddd21594 Bump eslint-plugin-jest from 26.4.6 to 26.5.3
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 26.4.6 to 26.5.3.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v26.4.6...v26.5.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 22:19:30 +00:00
Daz DeBoer
33ed11e54c Build outputs 2022-06-06 15:36:40 -06:00
Daz DeBoer
93c31ca3b5 Don't fail if the file-to-delete no longer exists
Fixes #308
2022-06-06 15:35:57 -06:00
Daz DeBoer
7a15005377 Avoid printing "reason unknown" for extract entries
This was happening when the main Gradle User Home entry was not saved due to
having an unchanged cache key.

Fixes #309
2022-06-06 15:07:13 -06:00
Daz DeBoer
e88ed3e650 Update README for v2.2.0 2022-06-06 12:34:02 -06:00
66 changed files with 2073 additions and 2543 deletions

View File

@@ -9,7 +9,7 @@ updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
interval: "weekly"
open-pull-requests-limit: 10
ignore:
- dependency-name: "@types/node"

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,6 @@
plugins {
id "com.gradle.enterprise" version "3.10.1"
id "com.gradle.enterprise" version "3.10.3"
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.7.2"
}
gradleEnterprise {

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,6 @@
plugins {
id("com.gradle.enterprise") version "3.10.1"
id("com.gradle.enterprise") version "3.10.3"
id("com.gradle.common-custom-user-data-gradle-plugin") version "1.7.2"
}
gradleEnterprise {

View File

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

View File

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

View File

@@ -2,6 +2,11 @@ name: CI-init-script-check
on:
push:
paths:
- '.github/workflows/**'
- 'src/resources/init-scripts/**'
- 'test/init-script-check/**'
workflow_dispatch:
jobs:
test-init-scripts:
@@ -17,5 +22,5 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v2 # Use a released version to avoid breakages
- name: Run integration tests
working-directory: test/test-init-scripts
working-directory: test/init-scripts
run: ./gradlew check

View File

@@ -8,9 +8,7 @@ on:
push:
branches:
- main
paths:
- '.github/workflows/**'
- 'dist/**'
- dependabot/**
jobs:
check:

View File

@@ -25,7 +25,10 @@ jobs:
run: ./gradlew assemble
- name: Build kotlin-dsl project without build scan
working-directory: .github/workflow-samples/kotlin-dsl
run: ./gradlew check --no-scan
run: ./gradlew assemble check --no-scan
- name: Build kotlin-dsl project with build scan publish failure
working-directory: .github/workflow-samples/kotlin-dsl
run: ./gradlew check -Dgradle.enterprise.url=https://not.valid.server
- name: Build groovy-dsl project
working-directory: .github/workflow-samples/groovy-dsl
run: ./gradlew assemble

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

@@ -85,6 +85,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 11
- uses: gradle/gradle-build-action@v2
with:
@@ -111,6 +112,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 11
- name: Setup and execute Gradle 'test' task
@@ -203,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.
@@ -218,17 +219,27 @@ For example, this means that all jobs executing a particular version of the Grad
### Using the caches read-only
In some circumstances, it makes sense for a Gradle invocation to read any existing cache entries but not to write changes back.
For example, you may want to write cache entries for builds on your `main` branch, but not for any PR build invocations.
By default, the `gradle-build-action` will only write to the cache from Jobs on the default (`main`/`master`) branch.
Jobs on other branches will read entries from the cache but will not write updated entries.
See [Optimizing cache effectiveness](#optimizing-cache-effectiveness) for a more detailed explanation.
You can enable read-only caching for any of the caches as follows:
In some circumstances it makes sense to change this default, and to configure a workflow Job to read existing cache entries but not to write changes back.
You can configure read-only caching for the `gradle-build-action` as follows:
```yaml
# Only write to the cache for builds on the 'main' branch.
# Only write to the cache for builds on the 'main' and 'release' branches. (Default is 'main' only.)
# Builds on other branches will only read existing entries from the cache.
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
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.
@@ -253,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:
@@ -267,18 +278,25 @@ 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.
#### Only write to the cache from the default branch
#### 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.
The exception to the is 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.
An easy way to reduce cache usage when you run builds on many different branches is to only permit your default branch to write to the cache,
with all other branch builds using `cache-read-only`. See [Using the caches read-only](#using-the-caches-read-only) for more details.
By default, the `gradle-build-action` will only _write_ to the cache for builds run on the default (`master`/`main`) branch.
Jobs run on other branches will only read from the cache. In most cases, this is the desired behaviour,
because Jobs run against other branches will benefit from the cache Gradle User Home from `main`,
without writing private cache entries that could lead to evicting shared entries.
If you have other long-lived development branches that would benefit from writing to the cache,
you can configure these by overriding the `cache-read-only` action parameter.
See [Using the caches read-only](#using-the-caches-read-only) for more details.
Similarly, you could use `cache-read-only` for certain jobs in the workflow, and instead have these jobs reuse the cache content from upstream jobs.
@@ -350,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.

View File

@@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,6 +0,0 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

View File

@@ -1,5 +0,0 @@
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build

View File

@@ -1,11 +0,0 @@
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation('junit:junit:4.12')
}

View File

@@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,185 +0,0 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

View File

@@ -1,104 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,10 +0,0 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html
*/
rootProject.name = 'basic'

View File

@@ -1,10 +0,0 @@
package basic;
import org.junit.Test;
public class BasicTest {
@Test
public void test() {
assert true;
}
}

555
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 {
@@ -1134,6 +1158,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
...getCompressionProgram(),
'-cf',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--exclude',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
@@ -2730,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
/***/ }),
@@ -2867,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__) {
@@ -64800,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:
@@ -64909,10 +65055,17 @@ class GradleStateCache {
return __awaiter(this, void 0, void 0, function* () {
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).key;
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY);
const entryListener = listener.entry(this.cacheDescription);
const gradleHomeEntryListener = listener.entry(this.cacheDescription);
if (restoredCacheKey && cacheKey === restoredCacheKey) {
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`);
entryListener.markUnchanged('cache key not changed');
for (const entryListener of listener.cacheEntries) {
if (entryListener === gradleHomeEntryListener) {
entryListener.markUnsaved('cache key not changed');
}
else {
entryListener.markUnsaved(`referencing '${this.cacheDescription}' cache entry not saved`);
}
}
return;
}
try {
@@ -64924,7 +65077,7 @@ class GradleStateCache {
}
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
const cachePath = this.getCachePath();
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, entryListener);
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, gradleHomeEntryListener);
return;
});
}
@@ -64964,13 +65117,13 @@ class GradleStateCache {
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
for (const initScriptFilename of initScriptFilenames) {
const initScriptContent = this.readResourceAsString(initScriptFilename);
const initScriptContent = this.readInitScriptAsString(initScriptFilename);
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
}
}
readResourceAsString(resource) {
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', resource);
readInitScriptAsString(resource) {
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource);
return fs_1.default.readFileSync(absolutePath, 'utf8');
}
debugReportGradleUserHomeSize(label) {
@@ -65052,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) {
@@ -65154,7 +65307,7 @@ class AbstractEntryExtractor {
const previouslyRestoredKey = (_a = previouslyRestoredEntries.find(x => x.artifactType === artifactType && x.pattern === pattern)) === null || _a === void 0 ? void 0 : _a.cacheKey;
if (previouslyRestoredKey === cacheKey) {
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
entryListener.markUnchanged('contents unchanged');
entryListener.markUnsaved('contents unchanged');
}
else {
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
@@ -65232,9 +65385,9 @@ class GradleHomeEntryExtractor extends AbstractEntryExtractor {
implicitDescendants: false,
followSymbolicLinks: false
});
for (const p of yield globber.glob()) {
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${p}`);
(0, cache_utils_1.tryDelete)(p);
for (const wrapperZip of yield globber.glob()) {
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${wrapperZip}`);
yield (0, cache_utils_1.tryDelete)(wrapperZip);
}
});
}
@@ -65285,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)];
}
@@ -65324,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';
}
@@ -65399,13 +65555,13 @@ class CacheEntryListener {
this.savedSize = 0;
return this;
}
markUnchanged(message) {
this.unchanged = message;
markUnsaved(message) {
this.unsaved = message;
return this;
}
}
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([
@@ -65418,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) {
@@ -65451,12 +65620,12 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
}
return '(Entry restored: partial match found)';
}
function getSavedMessage(entry, isCacheReadOnly) {
if (entry.unchanged) {
return `(Entry not saved: ${entry.unchanged})`;
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)';
@@ -65474,12 +65643,9 @@ function getSize(cacheEntries, predicate) {
return Math.round(bytes / (1024 * 1024));
}
function formatSize(bytes) {
if (bytes === undefined) {
if (bytes === undefined || bytes === 0) {
return '';
}
if (bytes === 0) {
return '0 (Entry already exists)';
}
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`;
}
@@ -65545,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;
@@ -65672,9 +65841,12 @@ exports.handleCacheFailure = handleCacheFailure;
function tryDelete(file) {
return __awaiter(this, void 0, void 0, function* () {
const maxAttempts = 5;
const stat = fs.lstatSync(file);
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
if (!fs.existsSync(file)) {
return;
}
try {
const stat = fs.lstatSync(file);
if (stat.isDirectory()) {
fs.rmdirSync(file, { recursive: true });
}
@@ -65768,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()) {
@@ -65780,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* () {
@@ -65789,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;
/***/ }),
@@ -65979,65 +66219,97 @@ var __importStar = (this && this.__importStar) || function (mod) {
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
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.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) {
core.info('Writing job summary');
if (buildResults.length === 0) {
core.debug('No Gradle build results found. Summary table will not be generated.');
}
else {
writeSummaryTable(buildResults);
}
(0, cache_reporting_1.logCachingReport)(cacheListener);
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);
return __awaiter(this, void 0, void 0, function* () {
core.info('Writing job summary');
if (buildResults.length === 0) {
core.debug('No Gradle build results found. Summary table will not be generated.');
}
else {
writeSummaryTable(buildResults);
}
(0, cache_reporting_1.writeCachingReport)(cacheListener);
yield core.summary.write();
});
}
exports.loadBuildResults = loadBuildResults;
exports.writeJobSummary = writeJobSummary;
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.logJobSummary = logJobSummary;
function writeSummaryTable(results) {
core.summary.addHeading('Gradle Builds', 3);
core.summary.addTable([
[
{ data: 'Root Project', header: true },
{ data: 'Tasks', header: true },
{ data: 'Gradle Version', header: true },
{ data: 'Outcome', header: true }
],
...results.map(result => [
result.rootProjectName,
result.requestedTasks,
result.gradleVersion,
renderOutcome(result)
])
]);
core.summary.addRaw('\n');
core.summary.addRaw(`
<table>
<tr>
<th>Root Project</th>
<th>Requested Tasks</th>
<th>Gradle Version</th>
<th>Build Outcome</th>
<th>Build Scan</th>
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
</table>
`);
}
function renderBuildResultRow(result) {
return `
<tr>
<td>${result.rootProjectName}</td>
<td>${result.requestedTasks}</td>
<td align='center'>${result.gradleVersion}</td>
<td align='center'>${renderOutcome(result)}</td>
<td>${renderBuildScan(result)}</td>
</tr>`;
}
function renderOutcome(result) {
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build';
const outcomePart = result.buildFailed ? 'FAILED-red' : 'SUCCESS-brightgreen';
const badgeUrl = `https://img.shields.io/badge/${labelPart}-${outcomePart}?logo=Gradle`;
const badgeHtml = `<img src="${badgeUrl}" alt="Gradle Build">`;
const targetUrl = result.buildScanUri ? result.buildScanUri : '#';
return result.buildFailed ? ':x:' : ':white_check_mark:';
}
function renderBuildScan(result) {
if (result.buildScanFailed) {
return renderBuildScanBadge('PUBLISH_FAILED', 'orange', 'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting');
}
if (result.buildScanUri) {
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri);
}
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com');
}
function renderBuildScanBadge(outcomeText, outcomeColor, targetUrl) {
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`;
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`;
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
}
function logSummaryTable(results) {
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('============================');
}
/***/ }),
@@ -66383,17 +66655,22 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.complete = exports.setup = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const fs = __importStar(__nccwpck_require__(7147));
const summary_1 = __nccwpck_require__(1327);
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';
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary';
function shouldGenerateJobSummary() {
if (!process.env[summary_1.SUMMARY_ENV_VAR]) {
return false;
}
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER);
}
function setup(buildRootDirectory) {
@@ -66418,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);
}
});
}
@@ -66454,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

555
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 {
@@ -1134,6 +1158,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
...getCompressionProgram(),
'-cf',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--exclude',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P',
'-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
@@ -2730,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
/***/ }),
@@ -2867,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__) {
@@ -63851,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:
@@ -63960,10 +64106,17 @@ class GradleStateCache {
return __awaiter(this, void 0, void 0, function* () {
const cacheKey = (0, cache_utils_1.generateCacheKey)(this.cacheName).key;
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY);
const entryListener = listener.entry(this.cacheDescription);
const gradleHomeEntryListener = listener.entry(this.cacheDescription);
if (restoredCacheKey && cacheKey === restoredCacheKey) {
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`);
entryListener.markUnchanged('cache key not changed');
for (const entryListener of listener.cacheEntries) {
if (entryListener === gradleHomeEntryListener) {
entryListener.markUnsaved('cache key not changed');
}
else {
entryListener.markUnsaved(`referencing '${this.cacheDescription}' cache entry not saved`);
}
}
return;
}
try {
@@ -63975,7 +64128,7 @@ class GradleStateCache {
}
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`);
const cachePath = this.getCachePath();
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, entryListener);
yield (0, cache_utils_1.saveCache)(cachePath, cacheKey, gradleHomeEntryListener);
return;
});
}
@@ -64015,13 +64168,13 @@ class GradleStateCache {
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy'];
for (const initScriptFilename of initScriptFilenames) {
const initScriptContent = this.readResourceAsString(initScriptFilename);
const initScriptContent = this.readInitScriptAsString(initScriptFilename);
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
fs_1.default.writeFileSync(initScriptPath, initScriptContent);
}
}
readResourceAsString(resource) {
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', resource);
readInitScriptAsString(resource) {
const absolutePath = path_1.default.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource);
return fs_1.default.readFileSync(absolutePath, 'utf8');
}
debugReportGradleUserHomeSize(label) {
@@ -64103,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) {
@@ -64205,7 +64358,7 @@ class AbstractEntryExtractor {
const previouslyRestoredKey = (_a = previouslyRestoredEntries.find(x => x.artifactType === artifactType && x.pattern === pattern)) === null || _a === void 0 ? void 0 : _a.cacheKey;
if (previouslyRestoredKey === cacheKey) {
(0, cache_utils_1.cacheDebug)(`No change to previously restored ${artifactType}. Not saving.`);
entryListener.markUnchanged('contents unchanged');
entryListener.markUnsaved('contents unchanged');
}
else {
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`);
@@ -64283,9 +64436,9 @@ class GradleHomeEntryExtractor extends AbstractEntryExtractor {
implicitDescendants: false,
followSymbolicLinks: false
});
for (const p of yield globber.glob()) {
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${p}`);
(0, cache_utils_1.tryDelete)(p);
for (const wrapperZip of yield globber.glob()) {
(0, cache_utils_1.cacheDebug)(`Deleting wrapper zip: ${wrapperZip}`);
yield (0, cache_utils_1.tryDelete)(wrapperZip);
}
});
}
@@ -64336,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)];
}
@@ -64375,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';
}
@@ -64450,13 +64606,13 @@ class CacheEntryListener {
this.savedSize = 0;
return this;
}
markUnchanged(message) {
this.unchanged = message;
markUnsaved(message) {
this.unsaved = message;
return this;
}
}
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([
@@ -64469,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) {
@@ -64502,12 +64671,12 @@ function getRestoredMessage(entry, isCacheWriteOnly) {
}
return '(Entry restored: partial match found)';
}
function getSavedMessage(entry, isCacheReadOnly) {
if (entry.unchanged) {
return `(Entry not saved: ${entry.unchanged})`;
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)';
@@ -64525,12 +64694,9 @@ function getSize(cacheEntries, predicate) {
return Math.round(bytes / (1024 * 1024));
}
function formatSize(bytes) {
if (bytes === undefined) {
if (bytes === undefined || bytes === 0) {
return '';
}
if (bytes === 0) {
return '0 (Entry already exists)';
}
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`;
}
@@ -64596,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;
@@ -64723,9 +64892,12 @@ exports.handleCacheFailure = handleCacheFailure;
function tryDelete(file) {
return __awaiter(this, void 0, void 0, function* () {
const maxAttempts = 5;
const stat = fs.lstatSync(file);
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
if (!fs.existsSync(file)) {
return;
}
try {
const stat = fs.lstatSync(file);
if (stat.isDirectory()) {
fs.rmdirSync(file, { recursive: true });
}
@@ -64819,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()) {
@@ -64831,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* () {
@@ -64840,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;
/***/ }),
@@ -64899,65 +65139,97 @@ var __importStar = (this && this.__importStar) || function (mod) {
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
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.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) {
core.info('Writing job summary');
if (buildResults.length === 0) {
core.debug('No Gradle build results found. Summary table will not be generated.');
}
else {
writeSummaryTable(buildResults);
}
(0, cache_reporting_1.logCachingReport)(cacheListener);
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);
return __awaiter(this, void 0, void 0, function* () {
core.info('Writing job summary');
if (buildResults.length === 0) {
core.debug('No Gradle build results found. Summary table will not be generated.');
}
else {
writeSummaryTable(buildResults);
}
(0, cache_reporting_1.writeCachingReport)(cacheListener);
yield core.summary.write();
});
}
exports.loadBuildResults = loadBuildResults;
exports.writeJobSummary = writeJobSummary;
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.logJobSummary = logJobSummary;
function writeSummaryTable(results) {
core.summary.addHeading('Gradle Builds', 3);
core.summary.addTable([
[
{ data: 'Root Project', header: true },
{ data: 'Tasks', header: true },
{ data: 'Gradle Version', header: true },
{ data: 'Outcome', header: true }
],
...results.map(result => [
result.rootProjectName,
result.requestedTasks,
result.gradleVersion,
renderOutcome(result)
])
]);
core.summary.addRaw('\n');
core.summary.addRaw(`
<table>
<tr>
<th>Root Project</th>
<th>Requested Tasks</th>
<th>Gradle Version</th>
<th>Build Outcome</th>
<th>Build Scan</th>
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
</table>
`);
}
function renderBuildResultRow(result) {
return `
<tr>
<td>${result.rootProjectName}</td>
<td>${result.requestedTasks}</td>
<td align='center'>${result.gradleVersion}</td>
<td align='center'>${renderOutcome(result)}</td>
<td>${renderBuildScan(result)}</td>
</tr>`;
}
function renderOutcome(result) {
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build';
const outcomePart = result.buildFailed ? 'FAILED-red' : 'SUCCESS-brightgreen';
const badgeUrl = `https://img.shields.io/badge/${labelPart}-${outcomePart}?logo=Gradle`;
const badgeHtml = `<img src="${badgeUrl}" alt="Gradle Build">`;
const targetUrl = result.buildScanUri ? result.buildScanUri : '#';
return result.buildFailed ? ':x:' : ':white_check_mark:';
}
function renderBuildScan(result) {
if (result.buildScanFailed) {
return renderBuildScanBadge('PUBLISH_FAILED', 'orange', 'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting');
}
if (result.buildScanUri) {
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri);
}
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com');
}
function renderBuildScanBadge(outcomeText, outcomeColor, targetUrl) {
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`;
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`;
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`;
}
function logSummaryTable(results) {
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('============================');
}
/***/ }),
@@ -65067,17 +65339,22 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.complete = exports.setup = void 0;
const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514));
const fs = __importStar(__nccwpck_require__(7147));
const summary_1 = __nccwpck_require__(1327);
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';
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary';
function shouldGenerateJobSummary() {
if (!process.env[summary_1.SUMMARY_ENV_VAR]) {
return false;
}
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER);
}
function setup(buildRootDirectory) {
@@ -65102,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);
}
});
}
@@ -65138,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

2355
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.5",
"@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.0",
"@types/jest": "28.1.4",
"@types/node": "16.11.21",
"@types/unzipper": "0.10.5",
"@typescript-eslint/parser": "5.27.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.4.6",
"jest": "28.1.0",
"eslint-plugin-jest": "26.5.3",
"jest": "28.1.2",
"js-yaml": "4.1.0",
"patch-package": "6.4.7",
"prettier": "2.6.2",
"ts-jest": "28.0.4",
"typescript": "4.7.3"
"prettier": "2.7.1",
"ts-jest": "28.0.5",
"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

@@ -94,11 +94,18 @@ export class GradleStateCache {
async save(listener: CacheListener): Promise<void> {
const cacheKey = generateCacheKey(this.cacheName).key
const restoredCacheKey = core.getState(RESTORED_CACHE_KEY_KEY)
const entryListener = listener.entry(this.cacheDescription)
const gradleHomeEntryListener = listener.entry(this.cacheDescription)
if (restoredCacheKey && cacheKey === restoredCacheKey) {
core.info(`Cache hit occurred on the cache key ${cacheKey}, not saving cache.`)
entryListener.markUnchanged('cache key not changed')
for (const entryListener of listener.cacheEntries) {
if (entryListener === gradleHomeEntryListener) {
entryListener.markUnsaved('cache key not changed')
} else {
entryListener.markUnsaved(`referencing '${this.cacheDescription}' cache entry not saved`)
}
}
return
}
@@ -111,7 +118,7 @@ export class GradleStateCache {
core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`)
const cachePath = this.getCachePath()
await saveCache(cachePath, cacheKey, entryListener)
await saveCache(cachePath, cacheKey, gradleHomeEntryListener)
return
}
@@ -168,15 +175,15 @@ export class GradleStateCache {
private initializeGradleUserHome(gradleUserHome: string, initScriptsDir: string): void {
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy']
for (const initScriptFilename of initScriptFilenames) {
const initScriptContent = this.readResourceAsString(initScriptFilename)
const initScriptContent = this.readInitScriptAsString(initScriptFilename)
const initScriptPath = path.resolve(initScriptsDir, initScriptFilename)
fs.writeFileSync(initScriptPath, initScriptContent)
}
}
private readResourceAsString(resource: string): string {
private readInitScriptAsString(resource: string): string {
// Resolving relative to __dirname will allow node to find the resource at runtime
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', resource)
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource)
return fs.readFileSync(absolutePath, 'utf8')
}

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'
@@ -213,7 +213,7 @@ abstract class AbstractEntryExtractor {
if (previouslyRestoredKey === cacheKey) {
cacheDebug(`No change to previously restored ${artifactType}. Not saving.`)
entryListener.markUnchanged('contents unchanged')
entryListener.markUnsaved('contents unchanged')
} else {
core.info(`Caching ${artifactType} with path '${pattern}' and cache key: ${cacheKey}`)
await saveCache([pattern], cacheKey, entryListener)
@@ -312,9 +312,9 @@ export class GradleHomeEntryExtractor extends AbstractEntryExtractor {
followSymbolicLinks: false
})
for (const p of await globber.glob()) {
cacheDebug(`Deleting wrapper zip: ${p}`)
tryDelete(p)
for (const wrapperZip of await globber.glob()) {
cacheDebug(`Deleting wrapper zip: ${wrapperZip}`)
await tryDelete(wrapperZip)
}
}

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'
}
@@ -64,7 +66,7 @@ export class CacheEntryListener {
savedKey: string | undefined
savedSize: number | undefined
unchanged: string | undefined
unsaved: string | undefined
constructor(entryName: string) {
this.entryName = entryName
@@ -98,13 +100,13 @@ export class CacheEntryListener {
return this
}
markUnchanged(message: string): CacheEntryListener {
this.unchanged = message
markUnsaved(message: string): CacheEntryListener {
this.unsaved = message
return this
}
}
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 {
if (entry.unchanged) {
return `(Entry not saved: ${entry.unchanged})`
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)'
@@ -190,11 +210,8 @@ function getSize(
}
function formatSize(bytes: number | undefined): string {
if (bytes === undefined) {
if (bytes === undefined || bytes === 0) {
return ''
}
if (bytes === 0) {
return '0 (Entry already exists)'
}
return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)`
}

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)
}
@@ -198,9 +201,12 @@ export function handleCacheFailure(error: unknown, message: string): void {
*/
export async function tryDelete(file: string): Promise<void> {
const maxAttempts = 5
const stat = fs.lstatSync(file)
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
if (!fs.existsSync(file)) {
return
}
try {
const stat = fs.lstatSync(file)
if (stat.isDirectory()) {
fs.rmdirSync(file, {recursive: true})
} else {

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,19 +1,8 @@
import * as core from '@actions/core'
import fs from 'fs'
import path from 'path'
import {logCachingReport, CacheListener} from './cache-reporting'
import {BuildResult} from './build-results'
import {writeCachingReport, CacheListener, logCachingReport} 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
}
export function writeJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): void {
export async function writeJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> {
core.info('Writing job summary')
if (buildResults.length === 0) {
@@ -22,49 +11,84 @@ export function writeJobSummary(buildResults: BuildResult[], cacheListener: Cach
writeSummaryTable(buildResults)
}
logCachingReport(cacheListener)
writeCachingReport(cacheListener)
core.summary.write()
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 {
core.summary.addHeading('Gradle Builds', 3)
core.summary.addTable([
[
{data: 'Root Project', header: true},
{data: 'Tasks', header: true},
{data: 'Gradle Version', header: true},
{data: 'Outcome', header: true}
],
...results.map(result => [
result.rootProjectName,
result.requestedTasks,
result.gradleVersion,
renderOutcome(result)
])
])
core.summary.addRaw('\n')
core.summary.addRaw(`
<table>
<tr>
<th>Root Project</th>
<th>Requested Tasks</th>
<th>Gradle Version</th>
<th>Build Outcome</th>
<th>Build Scan™</th>
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
</table>
`)
}
function renderBuildResultRow(result: BuildResult): string {
return `
<tr>
<td>${result.rootProjectName}</td>
<td>${result.requestedTasks}</td>
<td align='center'>${result.gradleVersion}</td>
<td align='center'>${renderOutcome(result)}</td>
<td>${renderBuildScan(result)}</td>
</tr>`
}
function renderOutcome(result: BuildResult): string {
const labelPart = result.buildScanUri ? 'Build%20Scan%E2%84%A2' : 'Build'
const outcomePart = result.buildFailed ? 'FAILED-red' : 'SUCCESS-brightgreen'
const badgeUrl = `https://img.shields.io/badge/${labelPart}-${outcomePart}?logo=Gradle`
const badgeHtml = `<img src="${badgeUrl}" alt="Gradle Build">`
const targetUrl = result.buildScanUri ? result.buildScanUri : '#'
return result.buildFailed ? ':x:' : ':white_check_mark:'
}
function renderBuildScan(result: BuildResult): string {
if (result.buildScanFailed) {
return renderBuildScanBadge(
'PUBLISH_FAILED',
'orange',
'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting'
)
}
if (result.buildScanUri) {
return renderBuildScanBadge('PUBLISHED', '06A0CE', result.buildScanUri)
}
return renderBuildScanBadge('NOT_PUBLISHED', 'lightgrey', 'https://scans.gradle.com')
}
function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string {
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`
}
function logSummaryTable(results: BuildResult[]): void {
core.info('============================')
core.info('Gradle Builds')
core.info('----------------------------')
core.info('Root Project | Requested Tasks | Gradle Version | Build Outcome | Build Scan™')
core.info('----------------------------')
for (const result of results) {
core.info(
`${result.rootProjectName} | ${result.requestedTasks} | ${result.gradleVersion} | ${
result.buildFailed ? 'FAILED' : 'SUCCESS'
} | ${result.buildScanFailed ? 'Publish failed' : result.buildScanUri}`
)
}
core.info('============================')
}

View File

@@ -41,12 +41,19 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
gradleVersion: GradleVersion.current().version,
gradleHomeDir: getParameters().getGradleHomeDir().get(),
buildFailed: buildFailed,
buildScanUri: null
buildScanUri: null,
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

@@ -40,65 +40,33 @@ if (isTopLevelBuild) {
def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId) {
buildScanExtension.with {
def requestedTasks = gradle.startParameter.taskNames.join(" ")
def rootProjectName = rootProject.name
def rootProjectDir = rootProject.projectDir.absolutePath
def gradleVersion = GradleVersion.current().version
def gradleHomeDir = gradle.gradleHomeDir.absolutePath
def buildFailed = false
def buildResults = new BuildResults(invocationId, gradle, rootProject)
buildFinished { result ->
buildFailed = (result.failure != null)
buildResults.setBuildResult(result)
}
buildScanPublished { buildScan ->
def buildScanUri = buildScan.buildScanUri.toASCIIString()
def buildResults = [
rootProjectName: rootProjectName,
rootProjectDir: rootProjectDir,
requestedTasks: requestedTasks,
gradleVersion: gradleVersion,
gradleHomeDir: gradleHomeDir,
buildFailed: buildFailed,
buildScanUri: buildScanUri
]
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
buildResultsDir.mkdirs()
def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + invocationId + ".json")
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
if (buildResultsFile.exists()) {
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
} else {
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
}
buildResults.setBuildScanUri(buildScan.buildScanUri.toASCIIString())
buildResults.writeToResultsFile(true)
println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
}
onError { error ->
buildResults.setBuildScanFailed()
buildResults.writeToResultsFile(true)
}
}
}
def captureUsingBuildFinished(gradle, invocationId) {
gradle.buildFinished { result ->
def buildResults = [
rootProjectName: gradle.rootProject.name,
rootProjectDir: gradle.rootProject.rootDir.absolutePath,
requestedTasks: gradle.startParameter.taskNames.join(" "),
gradleVersion: GradleVersion.current().version,
gradleHomeDir: gradle.gradleHomeDir.absolutePath,
buildFailed: result.failure != null,
buildScanUri: null
]
def buildResults = new BuildResults(invocationId, gradle, gradle.rootProject)
buildResults.setBuildResult(result)
buildResults.writeToResultsFile(false)
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
buildResultsDir.mkdirs()
def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + invocationId + ".json")
// Don't overwrite file generated by build-scan plugin if present (which has build-scan-uri)
if (!buildResultsFile.exists()) {
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
}
}
}
@@ -106,3 +74,55 @@ def captureUsingBuildService(settings, invocationId) {
gradle.ext.invocationId = invocationId
apply from: 'build-result-capture-service.plugin.groovy'
}
class BuildResults {
def invocationId
def buildResults
BuildResults(String invocationId, def gradle, def rootProject) {
this.invocationId = invocationId
buildResults = [
rootProjectName: rootProject.name,
rootProjectDir: rootProject.projectDir.absolutePath,
requestedTasks: gradle.startParameter.taskNames.join(" "),
gradleVersion: GradleVersion.current().version,
gradleHomeDir: gradle.gradleHomeDir.absolutePath,
buildFailed: false,
buildScanUri: null,
buildScanFailed: false
]
}
def setBuildResult(def result) {
buildResults['buildFailed'] = result.failure != null
}
def setBuildScanUri(def buildScanUrl) {
buildResults['buildScanUri'] = buildScanUrl
}
def setBuildScanFailed() {
buildResults['buildScanFailed'] = true
}
def writeToResultsFile(boolean overwrite) {
def runnerTempDir = System.getenv("RUNNER_TEMP")
def githubActionStep = System.getenv("GITHUB_ACTION")
if (!runnerTempDir || !githubActionStep) {
return
}
def buildResultsDir = new File(runnerTempDir, ".build-results")
buildResultsDir.mkdirs()
def buildResultsFile = new File(buildResultsDir, githubActionStep + invocationId + ".json")
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
if (buildResultsFile.exists()) {
if (overwrite) {
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
}
} else {
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
}
}
}

View File

@@ -1,12 +1,14 @@
import * as core from '@actions/core'
import * as exec from '@actions/exec'
import * as fs from 'fs'
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
import * as path from 'path'
import * as os from 'os'
import * as caches from './caches'
import {logJobSummary, writeJobSummary} from './job-summary'
import {loadBuildResults} from './build-results'
import {CacheListener} from './cache-reporting'
import {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'
@@ -14,6 +16,11 @@ const CACHE_LISTENER = 'CACHE_LISTENER'
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary'
function shouldGenerateJobSummary(): boolean {
// Check if Job Summary is supported on this platform
if (!process.env[SUMMARY_ENV_VAR]) {
return false
}
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER)
}
@@ -44,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)
}
}
@@ -86,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

@@ -45,6 +45,7 @@ class BaseInitScriptTest extends Specification {
static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw'
static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token'
static final String ROOT_PROJECT_NAME = 'test-init-script'
boolean failScanUpload = false
File settingsFile
File buildFile
@@ -59,6 +60,10 @@ class BaseInitScriptTest extends Specification {
handlers {
post('in/:gradleVersion/:pluginVersion') {
if (failScanUpload) {
context.response.status(401).send()
return
}
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
def body = [
id : PUBLIC_BUILD_SCAN_ID,
@@ -72,6 +77,10 @@ class BaseInitScriptTest extends Specification {
}
prefix('scans/publish') {
post('gradle/:pluginVersion/token') {
if (failScanUpload) {
context.response.status(401).send()
return
}
def pluginVersion = context.pathTokens.pluginVersion
def scanUrlString = "${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID"
def body = [
@@ -85,6 +94,10 @@ class BaseInitScriptTest extends Specification {
.send(jsonWriter.writeValueAsBytes(body))
}
post('gradle/:pluginVersion/upload') {
if (failScanUpload) {
context.response.status(401).send()
return
}
context.request.getBody(1024 * 1024 * 10).then {
context.response
.contentType('application/vnd.gradle.scan-upload-ack+json')
@@ -100,7 +113,7 @@ class BaseInitScriptTest extends Specification {
settingsFile = new File(testProjectDir, 'settings.gradle')
buildFile = new File(testProjectDir, 'build.gradle')
File srcInitScriptsDir = new File("../../src/resources")
File srcInitScriptsDir = new File("../../src/resources/init-scripts")
File targetInitScriptsDir = new File(testProjectDir, "initScripts")
targetInitScriptsDir.mkdirs()
@@ -187,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

@@ -118,7 +118,37 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
testGradleVersion << CONFIGURATION_CACHE_VERSIONS
}
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean hasBuildScan) {
def "produces build results file for failing build on #testGradleVersion when build scan publish fails"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
declareGePluginApplication(testGradleVersion.gradleVersion)
addFailingTaskToBuild()
failScanUpload = true
runAndFail(['expectFailure'], initScript, testGradleVersion.gradleVersion)
then:
assertResults('expectFailure', testGradleVersion, true, false, true)
where:
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
assert results['rootProjectDir'] == testProjectDir.canonicalPath
@@ -127,6 +157,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assert results['gradleHomeDir'] != null
assert results['buildFailed'] == hasFailure
assert results['buildScanUri'] == (hasBuildScan ? "${mockScansServer.address}s/${PUBLIC_BUILD_SCAN_ID}" : null)
assert results['buildScanFailed'] == scanUploadFailed
}
private File getBuildResultFile() {

View File

@@ -1,4 +1,4 @@
import {CacheEntryListener, CacheListener} from '../src/cache-reporting'
import {CacheEntryListener, CacheListener} from '../../src/cache-reporting'
describe('caching report', () => {
describe('reports not fully restored', () => {

View File

@@ -1,4 +1,4 @@
import * as cacheUtils from '../src/cache-utils'
import * as cacheUtils from '../../src/cache-utils'
describe('cacheUtils-utils', () => {
describe('can hash', () => {