Compare commits

...

68 Commits

Author SHA1 Message Date
daz
e24011a3b5 Update dependency-submission action for 3.2.0
- Point to `setup-gradle` v3.2.0
- Add back in removed inputs
2024-04-04 13:33:06 -06:00
Daz DeBoer
eb261d5636 Document plugin authentication in README 2024-04-04 12:43:18 -06:00
Daz DeBoer
875d13660f Update NPM dependency versions 2024-04-04 12:34:24 -06:00
Daz DeBoer
a5a8ae9361 Bump to v1.3.0 of the dependency-graph plugin 2024-04-04 11:34:27 -06:00
Daz DeBoer
5fe1aec3c1 Develocity updates (#101)
- Switch to use `com.gradle.develocity` for plugin ID
- Switch to use `v3.17` for plugin version
- Update for change documentation URLs
- Update for changes to `develocity` DSL
2024-04-03 21:09:16 -06:00
daz
7be6c56c3d Build outputs 2024-04-03 20:57:44 -06:00
daz
7e87a5e8d9 Improve test coverage for different plugin versions 2024-04-03 20:57:44 -06:00
daz
518b14b196 Switch from com.gradle.enterprise to com.gradle.develocity 2024-04-03 19:05:27 -06:00
daz
81b3a2db60 Bump to Develocity plugin 3.17 2024-04-03 19:05:27 -06:00
daz
195c67f931 Use Develocity plugin v3.17 for build-scan-publish 2024-04-03 14:51:01 -06:00
Pavlo Shevchenko
5a171ce5b8 Inject Develocity plugin for versions 3.17 and above (#62)
To handle the rebranding of the GE plugin, this PR updates the inject-develocity init script 
to apply the `com.gradle.develocity` plugin if `3.17+` version of the plugin is requested.
2024-04-03 14:47:50 -06:00
Daz DeBoer
5512434733 Update README.md 2024-04-01 14:46:52 -06:00
daz
faecef076b Build outputs 2024-04-01 12:24:45 -06:00
dependabot[bot]
50af102149 Bump the npm-dependencies group in /sources with 2 updates
Bumps the npm-dependencies group in /sources with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser).


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

Updates `@typescript-eslint/parser` from 7.3.1 to 7.4.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/v7.4.0/packages/parser)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 12:24:45 -06:00
daz
cc54166e15 Truncate long values in job summary table
Fixes #35
2024-04-01 12:24:45 -06:00
daz
12646f8198 Clarify that Gradle Wrapper is assumed for examples 2024-04-01 12:24:45 -06:00
Iurii Ignatko
c276584302 Capture task input files when plugin not applied (#77)
This PR changes the behavior such that task input files are captured
when the environment variable is explicitly specified and for the cases
when the plugin is not applied.

---------

Co-authored-by: Alexis Tual <atual@gradle.com>
2024-03-25 16:34:45 +02:00
daz
393df4bfa2 Bump to Gradle 8.7 2024-03-23 09:32:57 -06:00
daz
7c03a8d3fb Build outputs 2024-03-21 22:14:09 -06:00
dependabot[bot]
e562ae9f4a Bump the npm-dependencies group in /sources with 3 updates
Bumps the npm-dependencies group in /sources with 3 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [typescript](https://github.com/Microsoft/TypeScript).


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

Updates `@typescript-eslint/parser` from 7.2.0 to 7.3.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/v7.3.1/packages/parser)

Updates `typescript` from 5.4.2 to 5.4.3
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.2...v5.4.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-21 22:14:09 -06:00
dependabot[bot]
0dfb0395f5 Bump com.fasterxml.jackson.dataformat:jackson-dataformat-smile
Bumps [com.fasterxml.jackson.dataformat:jackson-dataformat-smile](https://github.com/FasterXML/jackson-dataformats-binary) from 2.16.2 to 2.17.0.
- [Commits](https://github.com/FasterXML/jackson-dataformats-binary/compare/jackson-dataformats-binary-2.16.2...jackson-dataformats-binary-2.17.0)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-smile
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-21 22:14:09 -06:00
dependabot[bot]
8735d0c1bb Bump com.google.guava:guava in /.github/workflow-samples/kotlin-dsl
Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.0.0-jre to 33.1.0-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-21 21:52:55 -06:00
daz
a6050d4c14 Remove redundant method implementation 2024-03-21 21:52:16 -06:00
daz
ef7196c315 Ignore VScode config files 2024-03-21 21:52:16 -06:00
daz
60b8089f55 Avoid dirty state after unit-test execution 2024-03-12 22:15:37 +13:00
dependabot[bot]
9b415aef98 Bump undici from 5.27.2 to 5.28.3 in /sources
Bumps [undici](https://github.com/nodejs/undici) from 5.27.2 to 5.28.3.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.27.2...v5.28.3)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-12 16:51:38 +13:00
Daz DeBoer
3fe876afb8 Merge pull request #66 from gradle/dependency-updates
Dependency updates
2024-03-11 21:44:18 -06:00
daz
f4c37be1e8 Build outputs 2024-03-12 16:23:08 +13:00
daz
68b69be9d4 Update patch for @actions/cache@3.2.4 2024-03-12 16:17:03 +13:00
dependabot[bot]
f8d50e3e2b Bump the npm-dependencies group in /sources with 14 updates
Bumps the npm-dependencies group in /sources with 14 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) | `2.1.0` | `2.1.4` |
| [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) | `3.2.3` | `3.2.4` |
| [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) | `2.2.0` | `2.2.1` |
| [@octokit/rest](https://github.com/octokit/rest.js) | `19.0.13` | `20.0.2` |
| [@octokit/webhooks-types](https://github.com/octokit/webhooks) | `7.3.1` | `7.4.0` |
| [semver](https://github.com/npm/node-semver) | `7.5.4` | `7.6.0` |
| [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) | `29.5.11` | `29.5.12` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.10.0` | `20.11.26` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.19.1` | `7.2.0` |
| [eslint](https://github.com/eslint/eslint) | `8.56.0` | `8.57.0` |
| [eslint-plugin-github](https://github.com/github/eslint-plugin-github) | `4.10.1` | `4.10.2` |
| [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) | `27.6.3` | `27.9.0` |
| [prettier](https://github.com/prettier/prettier) | `3.2.4` | `3.2.5` |
| [typescript](https://github.com/Microsoft/TypeScript) | `5.3.3` | `5.4.2` |


Updates `@actions/artifact` from 2.1.0 to 2.1.4
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/artifact)

Updates `@actions/cache` from 3.2.3 to 3.2.4
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

Updates `@actions/http-client` from 2.2.0 to 2.2.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

Updates `@octokit/rest` from 19.0.13 to 20.0.2
- [Release notes](https://github.com/octokit/rest.js/releases)
- [Commits](https://github.com/octokit/rest.js/compare/v19.0.13...v20.0.2)

Updates `@octokit/webhooks-types` from 7.3.1 to 7.4.0
- [Release notes](https://github.com/octokit/webhooks/releases)
- [Commits](https://github.com/octokit/webhooks/compare/v7.3.1...v7.4.0)

Updates `semver` from 7.5.4 to 7.6.0
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.5.4...v7.6.0)

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

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

Updates `@typescript-eslint/parser` from 6.19.1 to 7.2.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/v7.2.0/packages/parser)

Updates `eslint` from 8.56.0 to 8.57.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.56.0...v8.57.0)

Updates `eslint-plugin-github` from 4.10.1 to 4.10.2
- [Release notes](https://github.com/github/eslint-plugin-github/releases)
- [Commits](https://github.com/github/eslint-plugin-github/compare/v4.10.1...v4.10.2)

Updates `eslint-plugin-jest` from 27.6.3 to 27.9.0
- [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/v27.6.3...v27.9.0)

Updates `prettier` from 3.2.4 to 3.2.5
- [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/3.2.4...3.2.5)

Updates `typescript` from 5.3.3 to 5.4.2
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.3.3...v5.4.2)

---
updated-dependencies:
- dependency-name: "@actions/artifact"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@actions/cache"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@actions/http-client"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@octokit/rest"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: "@octokit/webhooks-types"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: semver
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: eslint-plugin-github
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-12 16:14:02 +13:00
daz
07f64e2534 Bump jackson-dataformat-smile to 2.16.2 2024-03-12 16:13:40 +13:00
daz
cee9fbd6e2 Bump CCUD plugin to 1.13 2024-03-12 16:13:40 +13:00
Daz DeBoer
32f1033fd2 Fix dependabot config for relocated NPM sources 2024-03-11 21:06:42 -06:00
daz
7b589d9740 Apply plugin repository credentials for dependency graph plugin 2024-03-12 15:49:28 +13:00
Daz DeBoer
f58a414c4f Fix typo 2024-03-11 19:37:21 -06:00
Iurii Ignatko
e43d10f419 Add an ability to capture task input files (#58)
This PR adds an ability to enable/disable [capturing task input
files](https://docs.gradle.com/enterprise/gradle-plugin/#capturing_task_input_files)
in a build scan.

---------

Co-authored-by: Eric Haag <eah0592@gmail.com>
2024-03-06 17:53:10 +02:00
Iurii Ignatko
579fbbe722 Allow configuring credentials for custom Gradle plugin repository (#61) 2024-03-06 08:48:24 +02:00
Iurii Ignatko
b00d9dd511 Merge pull request #60 from gradle/welandaz/lifecycle-log-level-init-script
Change messages log level in init script
2024-03-05 09:08:59 +02:00
Iurii Ignatko
f091a59e67 Change messages log level in init script 2024-03-01 12:00:19 +02:00
Jerome Prinet
6800f3450a Configure Dependabot to monitor .github/actions 2024-02-19 21:46:36 -07:00
François Martin
9e899d11ad Improve documentation
- Improve grammar
- improve clarity
- Fix small mistakes and word duplications
2024-02-13 16:19:45 -07:00
daz
acc4561424 Remove unused changes.md 2024-02-13 13:51:03 -07:00
daz
e2b14c9dfc Run full-check on action.yml change 2024-02-13 13:10:30 -07:00
daz
417ae3ccd7 Prepare for v3.1.0 release 2024-02-13 13:04:08 -07:00
Daz DeBoer
8a945e8ba7 Document use of debug logging with dependency-submission 2024-02-13 09:38:01 -07:00
daz
b61dbd2545 Test no dependency-graph for failing build 2024-02-12 22:03:45 -07:00
daz
2262487821 Use v1.2.2 of dep-graph plugin 2024-02-12 21:41:04 -07:00
daz
aaf44989e3 Use v1.2.1 of dep-graph plugin 2024-02-11 18:22:33 -07:00
Daz DeBoer
09bd32c78f Improve documentation for debug logging 2024-02-11 18:18:43 -07:00
daz
4b284311c3 Disable cache debug logging for workflows
This logging can now be enabled on a case-by-case basis using
GitHub Actions debugging.
2024-02-11 18:00:40 -07:00
Daz DeBoer
5e512f6e1d Merge pull request #40 from gradle/dd/v3.1
Improvements in preparation for v3.1
2024-02-11 17:45:41 -07:00
dependabot[bot]
d31af7fbe2 Bump org.junit.jupiter:junit-jupiter
Bumps [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5) from 5.10.1 to 5.10.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.10.1...r5.10.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-11 17:37:17 -07:00
daz
b6ea7d5b78 Build outputs 2024-02-11 17:35:43 -07:00
daz
9eb8242410 Improvements to debug logging
- Enable cache debugging when ACTIONS_STEP_DEBUG is on
- Replace some info messages with debug
2024-02-11 17:35:10 -07:00
hfhbd
f4f7af32dc Configure --info and --stacktrace when GitHub ACTIONS_RUNNER_DEBUG is true
Fixes #6
2024-02-11 16:56:16 -07:00
daz
79414b4f92 Add link to workflow run from PR comment
Fixes #11
2024-02-11 16:53:03 -07:00
daz
e9c65b9fc0 Attempt to make build-scan links open in new tab
GitHub currently strips the target="_blank" from the rendered HTML,
but we'll leave this in since it's the desired behaviour.
2024-02-11 16:52:22 -07:00
daz
109be5d55b Disable isolated projects in dependency-submission
The 'resolveAllDependencies' task is incompatible with project isolation.
Pending a fix to the plugin, disable this feature when running the
dependency-submission action.

Fixes #39
2024-02-11 15:56:13 -07:00
Daz DeBoer
b776693a71 Fail nicely when dependency-submission is used after setup-gradle in the same Job (#37)
Previously, this would fail with a hard-to-diagnose error message.

Fixes #14
2024-02-08 23:16:54 -07:00
daz
2f23d645f2 Warn and make Gradle Wrapper script executable
Instead of failing the build, detect a non-executable wrapper file
and set the executable bit.

Fixes #17
2024-02-08 22:26:12 -07:00
daz
dfd22334ff Use gradle properties to disable features instead of CLI args
These gradle properties will be silently ignored on older Gradle versions,
whereas unknown command-line args will cause Gradle to fail.

Fixes #15
2024-02-08 21:55:52 -07:00
daz
9c837ee543 Test dependency-submission with gradle versions 2024-02-08 21:55:52 -07:00
Goooler
bc07b88bc0 Update Gradle 8.6 rc refs to the final version
https://github.com/gradle/gradle/releases/tag/v8.6.0

Signed-off-by: Goooler <wangzongler@gmail.com>
2024-02-08 21:38:25 -07:00
Daz DeBoer
7fda81ffd5 Document auto-publish of build scans 2024-01-31 13:04:12 -07:00
Daz DeBoer
e4ee7d7f94 Document process for resolving a vulnerability (#8) 2024-01-31 12:42:07 -07:00
Daz DeBoer
a02bb79881 Introduce a top-level section for "resolving a vulnerability" 2024-01-31 12:23:08 -07:00
Daz DeBoer
52d6180f95 Add 'finding dependency source' section to docs (#7) 2024-01-31 12:17:45 -07:00
daz
ec92e82947 Prepare for v3.0.0 release 2024-01-31 04:14:38 -07:00
74 changed files with 4279 additions and 1749 deletions

View File

@@ -6,6 +6,15 @@ registries:
username: dummy # Required by dependabot username: dummy # Required by dependabot
password: dummy # Required by dependabot password: dummy # Required by dependabot
updates: updates:
- package-ecosystem: "npm"
directory: "/sources"
schedule:
interval: "weekly"
groups:
npm-dependencies:
patterns:
- "*"
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
schedule: schedule:
@@ -14,16 +23,22 @@ updates:
github-actions: github-actions:
patterns: patterns:
- "*" - "*"
# github-actions with directory: "/" only monitors .github/workflows
- package-ecosystem: "npm" # https://github.com/dependabot/dependabot-core/issues/6345
directory: "/" - package-ecosystem: "github-actions"
directory: "/.github/actions/build-dist"
schedule: schedule:
interval: "weekly" interval: "weekly"
ignore:
- dependency-name: "@types/node" # Breaking change: update with next major release
- dependency-name: "@octokit/rest" # Tied to node version
groups: groups:
npm-dependencies: github-actions:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/.github/actions/download-dist"
schedule:
interval: "weekly"
groups:
github-actions:
patterns: patterns:
- "*" - "*"

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026 distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026 distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -1,13 +1,12 @@
plugins { plugins {
id "com.gradle.enterprise" version "3.16.2" id "com.gradle.develocity" version "3.17"
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.12.1" id "com.gradle.common-custom-user-data-gradle-plugin" version "1.13"
} }
gradleEnterprise { develocity {
buildScan { buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfServiceAgree = "yes" termsOfUseAgree = "yes"
publishAlways()
uploadInBackground = false uploadInBackground = false
} }
} }

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026 distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -8,9 +8,9 @@ repositories {
dependencies { dependencies {
api("org.apache.commons:commons-math3:3.6.1") api("org.apache.commons:commons-math3:3.6.1")
implementation("com.google.guava:guava:33.0.0-jre") implementation("com.google.guava:guava:33.1.0-jre")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
} }
tasks.test { tasks.test {

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026 distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -1,14 +1,13 @@
plugins { plugins {
id("com.gradle.enterprise") version "3.16.2" id("com.gradle.develocity") version "3.17"
id("com.gradle.common-custom-user-data-gradle-plugin") version "1.12.1" id("com.gradle.common-custom-user-data-gradle-plugin") version "1.13"
} }
gradleEnterprise { develocity {
buildScan { buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfServiceAgree = "yes" termsOfUseAgree = "yes"
publishAlways() uploadInBackground = false
isUploadInBackground = false
} }
} }

View File

@@ -1,12 +1,11 @@
plugins { plugins {
id "com.gradle.build-scan" version "3.16.2" id "com.gradle.develocity" version "3.17"
} }
gradleEnterprise { develocity {
buildScan { buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfServiceAgree = "yes" termsOfUseAgree = "yes"
publishAlways()
uploadInBackground = false uploadInBackground = false
} }
} }

View File

@@ -1,12 +1,11 @@
plugins { plugins {
id "com.gradle.enterprise" version "3.16.2" id "com.gradle.develocity" version "3.17"
} }
gradleEnterprise { develocity {
buildScan { buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfServiceAgree = "yes" termsOfUseAgree = "yes"
publishAlways()
uploadInBackground = false uploadInBackground = false
} }
} }

View File

@@ -0,0 +1 @@
// Required to keep dependabot happy

View File

@@ -0,0 +1,8 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# 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"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
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.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@@ -0,0 +1,92 @@
@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=.
@rem This is normally unused
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% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% 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!
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
:omega

View File

@@ -0,0 +1,20 @@
plugins {
id "com.gradle.develocity" version "3.17"
}
develocity {
buildScan {
termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfUseAgree = "yes"
uploadInBackground = false
}
}
rootProject.name = 'no-wrapper'
println "Using Gradle version: ${gradle.gradleVersion}"
def gradleVersionCheck = System.properties.gradleVersionCheck
if (gradleVersionCheck && gradle.gradleVersion != gradleVersionCheck) {
throw new RuntimeException("Got the wrong version: expected ${gradleVersionCheck} but was ${gradle.gradleVersion}")
}

View File

@@ -13,6 +13,7 @@ on:
paths: paths:
- '.github/**' - '.github/**'
- 'dist/**' - 'dist/**'
- '**/action.yml'
jobs: jobs:
action-inputs: action-inputs:

View File

@@ -24,7 +24,7 @@ jobs:
- name: Configure Gradle as default for unit test - name: Configure Gradle as default for unit test
uses: ./setup-gradle uses: ./setup-gradle
with: with:
gradle-version: 8.5 gradle-version: 8.7
- name: Run tests - name: Run tests
run: | run: |
npm install npm install

View File

@@ -4,9 +4,6 @@ on:
workflow_dispatch: workflow_dispatch:
push: push:
env:
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
many-gradle-builds: many-gradle-builds:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -38,6 +35,7 @@ jobs:
run: | run: |
./gradlew tasks --no-daemon ./gradlew tasks --no-daemon
./gradlew help check ./gradlew help check
./gradlew wrapper --gradle-version 8.7 --gradle-distribution-sha256-sum 544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
- name: Fail groovy-dsl project - name: Fail groovy-dsl project
working-directory: .github/workflow-samples/groovy-dsl working-directory: .github/workflow-samples/groovy-dsl
continue-on-error: true continue-on-error: true

View File

@@ -7,9 +7,6 @@ on:
permissions: permissions:
contents: read contents: read
env:
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
dependency-submission-save: dependency-submission-save:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -8,9 +8,6 @@ on:
permissions: permissions:
contents: write contents: write
env:
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
dependency-submission-submit: dependency-submission-submit:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -7,9 +7,6 @@ on:
permissions: permissions:
contents: write contents: write
env:
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
test-dependency-submission: test-dependency-submission:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -22,3 +19,43 @@ jobs:
build-root-directory: .github/workflow-samples/groovy-dsl build-root-directory: .github/workflow-samples/groovy-dsl
env: env:
GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository
test-gradle-versions:
strategy:
matrix:
gradle: [8.0.2, 7.6.4, 7.1.1, 6.9.4, 6.0.1, 5.6.4, 5.2.1]
include:
- gradle: 5.6.4
build-root-suffix: -gradle-5
- gradle: 5.2.1
build-root-suffix: -gradle-5
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Generate and submit dependencies
uses: ./dependency-submission
with:
gradle-version: ${{ matrix.gradle }}
build-root-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }}
env:
GITHUB_DEPENDENCY_GRAPH_REF: 'refs/tags/v0.0.1' # Use a different ref to avoid updating the real dependency graph for the repository
test-after-setup-gradle:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Setup Gradle
uses: ./setup-gradle
- name: Generate and submit dependencies
id: dependency-submission
uses: ./dependency-submission
continue-on-error: true
with:
build-root-directory: .github/workflow-samples/groovy-dsl
- name: Assert step failure
if: steps.dependency-submission.outcome != 'failure'
run: |
echo "Dependency submission step should fail after setup-gradle"
exit 1

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
action-inputs: action-inputs:

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: integ-test-cache-cleanup-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: integ-test-cache-cleanup-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
full-build: full-build:

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-caching-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: action-inputs-caching-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:
@@ -32,10 +31,10 @@ jobs:
uses: ./setup-gradle uses: ./setup-gradle
with: with:
cache-read-only: false # For testing, allow writing cache entries on non-default branches cache-read-only: false # For testing, allow writing cache entries on non-default branches
# Add "enterprise" to main cache entry but omit "notifications" # Add "application" to main cache entry but omit "notifications"
gradle-home-cache-includes: | gradle-home-cache-includes: |
caches caches
enterprise application
# Exclude build-cache from main cache entry # Exclude build-cache from main cache entry
gradle-home-cache-excludes: | gradle-home-cache-excludes: |
caches/build-cache-* caches/build-cache-*
@@ -62,7 +61,7 @@ jobs:
# Use the same configuration as used in the seed build # Use the same configuration as used in the seed build
gradle-home-cache-includes: | gradle-home-cache-includes: |
caches caches
enterprise application
gradle-home-cache-excludes: | gradle-home-cache-excludes: |
caches/build-cache-* caches/build-cache-*
caches/*/executionHistory caches/*/executionHistory

View File

@@ -15,9 +15,34 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
failing-build:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Download distribution if required
uses: ./.github/actions/download-dist
- name: Setup Gradle for dependency-graph generate
uses: ./setup-gradle
with:
dependency-graph: generate
dependency-graph-continue-on-failure: true
- name: Run build that will fail
id: gradle-build
continue-on-error: true
run: ./gradlew build fail
working-directory: .github/workflow-samples/groovy-dsl
- name: Check no dependency graph is generated
shell: bash
run: |
if [ ! -z "$(ls -A dependency-graph-reports)" ]; then
echo "Expected no dependency graph files to be generated"
ls -l dependency-graph-reports
exit 1
fi
unsupported-gradle-version-warning: unsupported-gradle-version-warning:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@@ -18,7 +18,6 @@ permissions:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
groovy-generate: groovy-generate:

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: detect-java-toolchain-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: detect-java-toolchain-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
# Test that pre-installed runner JDKs are detected # Test that pre-installed runner JDKs are detected

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: execution-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: execution-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
# Tests for executing with different Gradle versions. # Tests for executing with different Gradle versions.
@@ -46,6 +45,12 @@ jobs:
gradle-version: release-candidate gradle-version: release-candidate
build-root-directory: .github/workflow-samples/no-wrapper build-root-directory: .github/workflow-samples/no-wrapper
arguments: help arguments: help
- name: Test with non-executable wrapper
uses: ./setup-gradle
with:
gradle-version: wrapper
build-root-directory: .github/workflow-samples/non-executable-wrapper
arguments: help
gradle-versions: gradle-versions:
strategy: strategy:

View File

@@ -18,20 +18,21 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: provision-gradle-versions-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: provision-gradle-versions-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
inject-develocity: inject-develocity:
env: env:
DEVELOCITY_INJECTION_ENABLED: true DEVELOCITY_INJECTION_ENABLED: true
DEVELOCITY_URL: https://ge.solutions-team.gradle.com DEVELOCITY_URL: https://ge.solutions-team.gradle.com
DEVELOCITY_PLUGIN_VERSION: 3.16.2 DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
DEVELOCITY_CCUD_PLUGIN_VERSION: 1.12.1 DEVELOCITY_CCUD_PLUGIN_VERSION: 1.13
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # This env var has not (yet) been renamed/aliased in GE plugin 3.16.2 GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # required to test against GE plugin 3.16.2
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
strategy: strategy:
matrix: matrix:
gradle: [current, 7.6.2, 6.9.4, 5.6.4] gradle: [current, 7.6.2, 6.9.4, 5.6.4]
os: ${{fromJSON(inputs.runner-os)}} os: ${{fromJSON(inputs.runner-os)}}
plugin-version: [3.16.2, 3.17]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
@@ -82,8 +83,8 @@ jobs:
cache-read-only: false # For testing, allow writing cache entries on non-default branches cache-read-only: false # For testing, allow writing cache entries on non-default branches
gradle-version: ${{ matrix.gradle }} gradle-version: ${{ matrix.gradle }}
build-scan-publish: true build-scan-publish: true
build-scan-terms-of-service-url: "https://gradle.com/terms-of-service" build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-service-agree: "yes" build-scan-terms-of-use-agree: "yes"
- name: Run Gradle build - name: Run Gradle build
id: gradle id: gradle
working-directory: .github/workflow-samples/no-ge working-directory: .github/workflow-samples/no-ge

View File

@@ -18,7 +18,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-configuration-cache-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-configuration-cache-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build-groovy: seed-build-groovy:
@@ -43,7 +42,7 @@ jobs:
with: with:
cache-read-only: false # For testing, allow writing cache entries on non-default branches cache-read-only: false # For testing, allow writing cache entries on non-default branches
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6-rc-1 gradle-version: 8.6
- name: Groovy build with configuration-cache enabled - name: Groovy build with configuration-cache enabled
working-directory: .github/workflow-samples/groovy-dsl working-directory: .github/workflow-samples/groovy-dsl
run: gradle test --configuration-cache run: gradle test --configuration-cache
@@ -71,7 +70,7 @@ jobs:
with: with:
cache-read-only: true cache-read-only: true
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6-rc-1 gradle-version: 8.6
- name: Groovy build with configuration-cache enabled - name: Groovy build with configuration-cache enabled
id: execute id: execute
working-directory: .github/workflow-samples/groovy-dsl working-directory: .github/workflow-samples/groovy-dsl
@@ -111,7 +110,7 @@ jobs:
with: with:
cache-read-only: true cache-read-only: true
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6-rc-1 gradle-version: 8.6
- name: Check execute Gradle build with configuration cache enabled (but not restored) - name: Check execute Gradle build with configuration cache enabled (but not restored)
working-directory: .github/workflow-samples/groovy-dsl working-directory: .github/workflow-samples/groovy-dsl
run: gradle test --configuration-cache run: gradle test --configuration-cache
@@ -138,7 +137,7 @@ jobs:
with: with:
cache-read-only: false # For testing, allow writing cache entries on non-default branches cache-read-only: false # For testing, allow writing cache entries on non-default branches
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6-rc-1 gradle-version: 8.6
- name: Execute 'help' with configuration-cache enabled - name: Execute 'help' with configuration-cache enabled
working-directory: .github/workflow-samples/kotlin-dsl working-directory: .github/workflow-samples/kotlin-dsl
run: gradle help --configuration-cache run: gradle help --configuration-cache
@@ -166,7 +165,7 @@ jobs:
with: with:
cache-read-only: false # For testing, allow writing cache entries on non-default branches cache-read-only: false # For testing, allow writing cache entries on non-default branches
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6-rc-1 gradle-version: 8.6
- name: Execute 'test' with configuration-cache enabled - name: Execute 'test' with configuration-cache enabled
working-directory: .github/workflow-samples/kotlin-dsl working-directory: .github/workflow-samples/kotlin-dsl
run: gradle test --configuration-cache run: gradle test --configuration-cache
@@ -195,7 +194,7 @@ jobs:
with: with:
cache-read-only: true cache-read-only: true
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6-rc-1 gradle-version: 8.6
- name: Execute 'test' again with configuration-cache enabled - name: Execute 'test' again with configuration-cache enabled
id: execute id: execute
working-directory: .github/workflow-samples/kotlin-dsl working-directory: .github/workflow-samples/kotlin-dsl

View File

@@ -12,7 +12,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:

View File

@@ -12,7 +12,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-custom-gradle-home-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:

View File

@@ -16,7 +16,6 @@ env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-gradle-home-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-gradle-home-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-gradle-home GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-gradle-home
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-java-toolchain-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-java-toolchain-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-gradle-plugin-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-gradle-plugin-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:

View File

@@ -15,7 +15,6 @@ on:
env: env:
DOWNLOAD_DIST: ${{ inputs.download-dist }} DOWNLOAD_DIST: ${{ inputs.download-dist }}
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-kotlin-dsl-${{ inputs.cache-key-prefix }} GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: sample-kotlin-dsl-${{ inputs.cache-key-prefix }}
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
jobs: jobs:
seed-build: seed-build:

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.git
.vscode
actions.code-workspace

View File

@@ -4,8 +4,12 @@ This repository contains a set of GitHub Actions that are useful for building Gr
## The `setup-gradle` action ## The `setup-gradle` action
The `setup-gradle` action can be used to configure Gradle for optimal execution on any platform supported by GitHub Actions.
This replaces the previous `gradle/gradle-build-action`, which now delegates to this implementation. This replaces the previous `gradle/gradle-build-action`, which now delegates to this implementation.
The recommended way to execute any Gradle build is with the help of the [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html), and the examples assume that the Gradle Wrapper has been configured for the project. See [this example](setup-gradle/README.md#build-with-a-specific-gradle-version) if your project doesn't use the Gradle Wrapper.
### Example usage ### Example usage
```yaml ```yaml

View File

@@ -62,7 +62,7 @@ jobs:
uses: gradle/actions/dependency-submission@v3 uses: gradle/actions/dependency-submission@v3
with: with:
# Use a particular Gradle version instead of the configured wrapper. # Use a particular Gradle version instead of the configured wrapper.
gradle-version: 8.6-rc-2 gradle-version: 8.6
# The gradle project is not in the root of the repository. # The gradle project is not in the root of the repository.
build-root-directory: my-gradle-project build-root-directory: my-gradle-project
@@ -74,7 +74,130 @@ jobs:
dependency-graph: generate-and-upload dependency-graph: generate-and-upload
``` ```
## Limiting the scope of the dependency graph # Resolving a dependency vulnerability
## Finding the source of a dependency vulnerability
Once you have submitted a dependency graph, you may receive Dependabot Alerts warning about vulnerabilities in
dependencies of your project. In the case of transitive dependencies, it may not be obvious how that dependency is
used or what you can do to address the vulnerability alert.
The first step to investigating a Dependabot Alert is to determine the source of the dependency. One of the best ways to
do so is with a free Develocity Build Scan®, which makes it easy to explore the dependencies resolved in your build.
<img width="1069" alt="image" src="https://github.com/gradle/actions/assets/179734/3a637dfd-396c-4e94-8332-dcc6eb5a35ac">
In this example, we are searching for dependencies matching the name 'com.squareup.okio:okio' in the _Build Dependencies_ of
the project. You can easily see that this dependency originates from 'com.github.ben-manes:gradle-versions-plugin'.
Knowing the source of the dependency can help determine how to deal with the Dependabot Alert.
Note that you may need to look at both the _Dependencies_ and the _Build Dependencies_ of your project to find the
offending dependency.
### Publishing a Develocity Build Scan® from your dependency submission workflow
You can automatically publish a Build Scan on every run of `gradle/actions/dependency-submission`. Three input parameters are
required, one to enable publishing and two more to accept the [Develocity terms of use](https://gradle.com/help/legal-terms-of-use).
```yaml
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v3
with:
build-scan-publish: true
build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-use-agree: "yes"
```
### When you cannot publish a Build Scan®
If publishing a free Build Scan to https://scans.gradle.com isn't an option, and you don't have access to a private [Develocity
server](https://gradle.com/) for your project, you can obtain information about the each resolved dependency by running the `dependency-submission` workflow with debug logging enabled.
The simplest way to do so is to re-run the dependency-submission job with debug logging enabled:
<img width="665" alt="image" src="https://github.com/gradle/actions/assets/179734/d95b889a-09fb-4731-91f2-baebbf647e31">
When you do so, the Gradle build that generates the dependency-graph will include a log message for each dependency version included in the graph.
Given the details in one log message, you can run (locally) the built-in [dependencyInsight](https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html#dependency_insights) task
to determine exactly how the dependency was resolved.
For example, given the following message in the logs:
```
Detected dependency 'com.google.guava:guava:32.1.3-jre': project = ':my-subproject', configuration = 'compileClasspath'
```
You would run the following command locally:
```
./gradlew :my-subproject:dependencyInsight --configuration compileClasspath --dependency com.google.guava:guava:32.1.3-jre
```
#### Dealing with 'classpath' configuration
If the configuration value in the log message is "classpath" then instead of running `dependency-insight` you'll need to run the Gradle
`buildEnvironment` task.
For example, given the following message in the logs:
```
Detected dependency 'xerces:xercesImpl:2.12.2': project = ':my-subproject', configuration = 'classpath'
```
You would run the following command locally to expose the `xercesImpl` dependency:
```
./gradlew :my-subproject:buildEnvironment | grep -C 5 xercesImpl
```
## Updating the dependency version
Once you've discovered the source of the dependency, the most obvious fix is to update the dependency to a patched version that does not
suffer the vulnerability. For direct dependencies, this is often straightforward. But for transitive dependencies it can be tricky.
### Dependency source is specified directly in the build
If the dependency is used to compile your code or run your tests, it's normal for the underlying "source" of the dependency to have a
version configured directly in the build. For example, if you have a vulnerable version of `com.squareup.okio:okio` in your `compileClasspath`, then
it's likely you have a dependency like `com.squareup.moshi:moshi` configured as an `api` or `implementation` dependency.
In this case there are 2 possibilities:
1. There is a newer, compatible version of `com.squareup.moshi:moshi` available, and you can just bump the version number.
2. There isn't a newer, compatible version of `com.squareup.moshi:moshi`
In the second case, you can add a Dependency Constraint, to force the use of the newest version of `com.squareup.okio`:
```kotlin
dependencies {
implementation("com.squareup.moshi:moshi:1.12.0")
constraints {
// Force a newer version of okio in transitive resolution
implementation("com.squareup.okio:okio:3.6.0")
}
}
```
### Dependency source is a plugin classpath
If the vulnerable dependency is introduced by a Gradle plugin, again the best option is to look for a newer version of the plugin.
But if none is available, you can still use a dependency constraint to force a newer transitive version to be used.
The dependency constraint must be added to the `classpath` configuration of the buildscript that loads the plugin.
```kotlin
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
constraints {
// Force a newer version of okio in transitive resolution
classpath("com.squareup.okio:okio:3.6.0")
}
}
}
plugins {
id("com.github.ben-manes.versions") version("0.51.0")
}
```
## Limiting the dependencies that appear in the dependency graph
By default, the `dependency-submission` action attempts to detect all dependencies declared and used by your Gradle build. By default, the `dependency-submission` action attempts to detect all dependencies declared and used by your Gradle build.
At times it may helpful to limit the dependencies reported to GitHub, to avoid security alerts for dependencies that At times it may helpful to limit the dependencies reported to GitHub, to avoid security alerts for dependencies that
@@ -89,7 +212,7 @@ contribute to the dependency graph.
> These dependencies would be assigned to different scopes (eg development, runtime, testing) and the GitHub UI would make it easy to opt-in to security alerts for different dependency scopes. > These dependencies would be assigned to different scopes (eg development, runtime, testing) and the GitHub UI would make it easy to opt-in to security alerts for different dependency scopes.
> However, this functionality does not yet exist. > However, this functionality does not yet exist.
### Excluding certain Gradle projects from to the dependency graph ### Excluding certain Gradle projects from the dependency graph
If you do not want the dependency graph to include dependencies from every project in your build, If you do not want the dependency graph to include dependencies from every project in your build,
you can easily exclude certain projects from the dependency extraction process. you can easily exclude certain projects from the dependency extraction process.
@@ -102,7 +225,7 @@ not necessarily remove all dependencies _declared_ in that project. If another p
then it may transitively resolve dependencies declared in the excluded project: these dependencies will still be included then it may transitively resolve dependencies declared in the excluded project: these dependencies will still be included
in the generated dependency graph. in the generated dependency graph.
### Excluding certain Gradle configurations from to the dependency graph ### Excluding certain Gradle configurations from the dependency graph
Similarly to Gradle projects, it is possible to exclude a set of configuration instances from dependency graph generation, Similarly to Gradle projects, it is possible to exclude a set of configuration instances from dependency graph generation,
so that dependencies resolved by those configurations are not included. so that dependencies resolved by those configurations are not included.
@@ -128,19 +251,21 @@ jobs:
- name: Generate and submit dependency graph - name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v3 uses: gradle/actions/dependency-submission@v3
env: env:
# Exclude all dependencies that originate solely in the 'buildSrc' project
DEPENDENCY_GRAPH_EXCLUDE_PROJECTS: ':buildSrc' DEPENDENCY_GRAPH_EXCLUDE_PROJECTS: ':buildSrc'
DEPENDENCY_GRAPH_EXCLUDE_CONFIGURATIONS: 'test(Compile|Runtime)Classpath' # Exclude dependencies that are only resolved in test classpaths
DEPENDENCY_GRAPH_EXCLUDE_CONFIGURATIONS: '.*[Tt]est(Compile|Runtime)Classpath'
``` ```
### Other configuration options ### Other filtering options
The [GitHub Dependency Graph Gradle Plugin](https://plugins.gradle.org/plugin/org.gradle.github-dependency-graph-gradle-plugin) The [GitHub Dependency Graph Gradle Plugin](https://plugins.gradle.org/plugin/org.gradle.github-dependency-graph-gradle-plugin)
has other filtering options that may be useful. has other filtering options that may be useful.
See [the docs](https://github.com/gradle/github-dependency-graph-gradle-plugin?tab=readme-ov-file#filtering-which-gradle-configurations-contribute-to-the-dependency-graph) for details. See [the docs](https://github.com/gradle/github-dependency-graph-gradle-plugin?tab=readme-ov-file#filtering-which-gradle-configurations-contribute-to-the-dependency-graph) for details.
## Advance usage scenarios # Advance usage scenarios
### Using a custom plugin repository ## Using a custom plugin repository
By default, the action downloads the `github-dependency-graph-gradle-plugin` from the Gradle Plugin Portal (https://plugins.gradle.org). If your GitHub Actions environment does not have access to this URL, you can specify a custom plugin repository to use. By default, the action downloads the `github-dependency-graph-gradle-plugin` from the Gradle Plugin Portal (https://plugins.gradle.org). If your GitHub Actions environment does not have access to this URL, you can specify a custom plugin repository to use.
Do so by setting the `GRADLE_PLUGIN_REPOSITORY_URL` environment variable. Do so by setting the `GRADLE_PLUGIN_REPOSITORY_URL` environment variable.
@@ -158,7 +283,7 @@ jobs:
GRADLE_PLUGIN_REPOSITORY_URL: "https://gradle-plugins-proxy.mycorp.com" GRADLE_PLUGIN_REPOSITORY_URL: "https://gradle-plugins-proxy.mycorp.com"
``` ```
### Integrating the `dependency-review-action` ## Integrating the `dependency-review-action`
The GitHub [dependency-review-action](https://github.com/actions/dependency-review-action) helps you The GitHub [dependency-review-action](https://github.com/actions/dependency-review-action) helps you
understand dependency changes (and the security impact of these changes) for a pull request, understand dependency changes (and the security impact of these changes) for a pull request,
@@ -194,7 +319,7 @@ jobs:
Note that the `dependency-submission` action submits the dependency graph at the completion of the workflow Job. Note that the `dependency-submission` action submits the dependency graph at the completion of the workflow Job.
For this reason, the `dependency-review-action` must be executed in a dependent job, and not as a subsequent step in the job that generates the dependency graph. For this reason, the `dependency-review-action` must be executed in a dependent job, and not as a subsequent step in the job that generates the dependency graph.
### Usage with pull requests from public forked repositories ## Usage with pull requests from public forked repositories
This `contents: write` permission is [not available for any workflow that is triggered by a pull request submitted from a public forked repository](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). This `contents: write` permission is [not available for any workflow that is triggered by a pull request submitted from a public forked repository](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).
This limitation is designed to prevent a malicious pull request from effecting repository changes. This limitation is designed to prevent a malicious pull request from effecting repository changes.
@@ -275,7 +400,7 @@ jobs:
The `retry-on-snapshot-warnings-timeout` (in seconds) needs to be long enough to allow the entire `Generate and save dependency graph` and `Download and submit dependency graph` workflows (above) to complete. The `retry-on-snapshot-warnings-timeout` (in seconds) needs to be long enough to allow the entire `Generate and save dependency graph` and `Download and submit dependency graph` workflows (above) to complete.
## Gradle version compatibility # Gradle version compatibility
Dependency-graph generation is compatible with most versions of Gradle >= `5.2`, and is tested regularly against Dependency-graph generation is compatible with most versions of Gradle >= `5.2`, and is tested regularly against
Gradle versions `5.2.1`, `5.6.4`, `6.0.1`, `6.9.4`, `7.1.1` and `7.6.3`, as well as all patched versions of Gradle 8.x. Gradle versions `5.2.1`, `5.6.4`, `6.0.1`, `6.9.4`, `7.1.1` and `7.6.3`, as well as all patched versions of Gradle 8.x.

View File

@@ -37,22 +37,40 @@ inputs:
build-scan-publish: build-scan-publish:
description: | description: |
Set to 'true' to automatically publish build results as a Build Scan on scans.gradle.com. Set to 'true' to automatically publish build results as a Build Scan on scans.gradle.com.
For publication to succeed without user input, you must also provide values for `build-scan-terms-of-service-url` and 'build-scan-terms-of-service-agree'. For publication to succeed without user input, you must also provide values for `build-scan-terms-of-use-url` and 'build-scan-terms-of-use-agree'.
required: false required: false
default: false default: false
build-scan-terms-of-use-url:
description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/help/legal-terms-of-use'.
required: false
build-scan-terms-of-use-agree:
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
required: false
# DEPRECATED ACTION INPUTS
build-scan-terms-of-service-url: build-scan-terms-of-service-url:
description: The URL to the Build Scan® terms of service. This input must be set to 'https://gradle.com/terms-of-service'. description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service'.
required: false required: false
deprecation-message: The input has been renamed to align with the Develocity API. Use 'build-scan-terms-of-use-url' instead.
build-scan-terms-of-service-agree: build-scan-terms-of-service-agree:
description: Indicate that you agree to the Build Scan® terms of service. This input value must be "yes". description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
required: false required: false
deprecation-message: The input has been renamed to align with the Develocity API. Use 'build-scan-terms-of-use-agree' instead.
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Check no setup-gradle
shell: bash
run: |
if [ -n "${GRADLE_BUILD_ACTION_SETUP_COMPLETED}" ]; then
echo "The dependency-submission action cannot be used in the same Job as the setup-gradle action. Please use a separate Job for dependency submission."
exit 1
fi
- name: Generate dependency graph - name: Generate dependency graph
if: ${{ inputs.dependency-graph == 'generate-and-submit' || inputs.dependency-graph == 'generate-and-upload' }} if: ${{ inputs.dependency-graph == 'generate-and-submit' || inputs.dependency-graph == 'generate-and-upload' }}
uses: gradle/actions/setup-gradle@v3 uses: gradle/actions/setup-gradle@v3.2.0
with: with:
dependency-graph: ${{ inputs.dependency-graph }} dependency-graph: ${{ inputs.dependency-graph }}
dependency-graph-continue-on-failure: false dependency-graph-continue-on-failure: false
@@ -60,17 +78,18 @@ runs:
build-root-directory: ${{ inputs.build-root-directory }} build-root-directory: ${{ inputs.build-root-directory }}
cache-encryption-key: ${{ inputs.cache-encryption-key }} cache-encryption-key: ${{ inputs.cache-encryption-key }}
build-scan-publish: ${{ inputs.build-scan-publish }} build-scan-publish: ${{ inputs.build-scan-publish }}
build-scan-terms-of-service-url: ${{ inputs.build-scan-terms-of-service-url }} build-scan-terms-of-use-url: ${{ inputs.build-scan-terms-of-use-url || inputs.build-scan-terms-of-service-url }}
build-scan-terms-of-service-agree: ${{ inputs.build-scan-terms-of-service-agree }} build-scan-terms-of-use-agree: ${{ inputs.build-scan-terms-of-use-agree || inputs.build-scan-terms-of-service-agree }}
artifact-retention-days: 1 artifact-retention-days: 1
arguments: | arguments: |
--no-configure-on-demand -Dorg.gradle.configureondemand=false
--dependency-verification=off -Dorg.gradle.dependency.verification=off
-Dorg.gradle.unsafe.isolated-projects=false
:ForceDependencyResolutionPlugin_resolveAllDependencies :ForceDependencyResolutionPlugin_resolveAllDependencies
${{ inputs.additional-arguments }} ${{ inputs.additional-arguments }}
- name: Download and submit dependency graph - name: Download and submit dependency graph
if: ${{ inputs.dependency-graph == 'download-and-submit' }} if: ${{ inputs.dependency-graph == 'download-and-submit' }}
uses: gradle/actions/setup-gradle@v3 uses: gradle/actions/setup-gradle@v3.2.0
with: with:
dependency-graph: download-and-submit dependency-graph: download-and-submit
dependency-graph-continue-on-failure: false dependency-graph-continue-on-failure: false

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

View File

@@ -6,13 +6,13 @@ This GitHub Action can be used to configure Gradle for optimal execution on any
It is possible to directly invoke Gradle in your workflow, and the `actions/setup-java@v4` action provides a simple way to cache Gradle dependencies. It is possible to directly invoke Gradle in your workflow, and the `actions/setup-java@v4` action provides a simple way to cache Gradle dependencies.
However, the `setup-gradle` action offers a number of advantages over this approach: However, the `setup-gradle` action offers a several advantages over this approach:
- Easily [configure your workflow to use a specific version of Gradle](#choose-a-specific-gradle-version) using the `gradle-version` parameter. Gradle distributions are automatically downloaded and cached. - Easily [configure your workflow to use a specific version of Gradle](#choose-a-specific-gradle-version) using the `gradle-version` parameter. Gradle distributions are automatically downloaded and cached.
- More sophisticated and more efficient caching of Gradle User Home between invocations, compared to `setup-java` and most custom configurations using `actions/cache`. [More details below](#caching-build-state-between-jobs). - More sophisticated and more efficient caching of Gradle User Home between invocations, compared to `setup-java` and most custom configurations using `actions/cache`. [More details below](#caching-build-state-between-jobs).
- Detailed reporting of cache usage and cache configuration options allow you to [optimize the use of the GitHub actions cache](#optimizing-cache-effectiveness). - Detailed reporting of cache usage and cache configuration options allow you to [optimize the use of the GitHub actions cache](#optimizing-cache-effectiveness).
- [Generate and Submit a GitHub Dependency Graph](#github-dependency-graph-support) for your project, enabling Dependabot security alerts. - [Generate and Submit a GitHub Dependency Graph](#github-dependency-graph-support) for your project, enabling Dependabot security alerts.
- [Automatic capture of Build Scan® links](#build-reporting) from the build, making these easier to locate for workflow run. - [Automatic capture of Build Scan® links](#build-reporting) from the build, making them easier to locate in workflow runs.
The `setup-gradle` action is designed to provide these benefits with minimal configuration. The `setup-gradle` action is designed to provide these benefits with minimal configuration.
These features work both when Gradle is executed via `setup-gradle` and for any Gradle execution in subsequent steps. These features work both when Gradle is executed via `setup-gradle` and for any Gradle execution in subsequent steps.
@@ -20,7 +20,9 @@ These features work both when Gradle is executed via `setup-gradle` and for any
## General usage ## General usage
The `setup-gradle` action works by configuring environment variables and by adding a set of Gradle init-scripts to the Gradle User Home. These will apply to all Gradle executions on the runner, no matter how Gradle is invoked. The `setup-gradle` action works by configuring environment variables and by adding a set of Gradle init-scripts to the Gradle User Home. These will apply to all Gradle executions on the runner, no matter how Gradle is invoked.
This means that if you have an existing workflow that executes Gradle with a `run` step, you can add an initial "Setup Gradle" Step to benefit from caching, build-scan capture and other features of this action. This means that if you have an existing workflow that executes Gradle with a `run` step, you can add an initial "Setup Gradle" Step to benefit from caching, build-scan capture, and other features of this action.
The recommended way to execute any Gradle build is with the help of the [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html), and the following examples assume that the Gradle Wrapper has been configured for the project. See [this example](#build-with-a-specific-gradle-version) if your project doesn't use the Gradle Wrapper.
```yaml ```yaml
@@ -46,15 +48,18 @@ jobs:
run: ./gradlew build run: ./gradlew build
``` ```
## Choose a specific Gradle version ## Build with a specific Gradle version
The `setup-gradle` action can download and install a specified Gradle version, adding this installed version to the PATH. The `setup-gradle` action can download and install a specified Gradle version, adding this installed version to the PATH.
Downloaded Gradle versions are stored in the GitHub Actions cache, to avoid requiring downloading again later. Downloaded Gradle versions are stored in the GitHub Actions cache, to avoid having to download them again later.
```yaml ```yaml
- uses: gradle/actions/setup-gradle@v3 - name: Setup Gradle 8.5
uses: gradle/actions/setup-gradle@v3
with: with:
gradle-version: 6.5 gradle-version: 8.5
- name: Build with Gradle 8.5
run: gradle build
``` ```
The `gradle-version` parameter can be set to any valid Gradle version. The `gradle-version` parameter can be set to any valid Gradle version.
@@ -97,15 +102,15 @@ jobs:
## Caching build state between Jobs ## Caching build state between Jobs
The `setup-gradle` action will use the GitHub Actions cache to save and restore reusable state that may be speed up a subsequent build invocation. This includes most content that is downloaded from the internet as part of a build, as well as expensive to create content like compiled build scripts, transformed Jar files, etc. The `setup-gradle` action will use the GitHub Actions cache to save and restore reusable state that may speed up subsequent build invocations. This includes most content that is downloaded from the internet as part of a build, as well as expensive to create content like compiled build scripts, transformed Jar files, etc.
The state that is cached includes: The cached state includes:
- Any distributions downloaded to satisfy a `gradle-version` parameter ; - Any distributions downloaded to satisfy a `gradle-version` parameter.
- A subset of the Gradle User Home directory, including downloaded dependencies, wrapper distributions, and the local build cache ; - A subset of the Gradle User Home directory, including downloaded dependencies, wrapper distributions, and the local build cache.
To reduce the space required for caching, this action makes a best effort to reduce duplication in cache entries. To reduce the space required for caching, this action attempts to reduce duplication in cache entries on a best effort basis.
State will be restored from the cache during the first `setup-gradle` step for any workflow job, and cache entries will be written back to the cache at the end of the job, after all Gradle executions have completed. The state will be restored from the cache during the first `setup-gradle` step for any workflow job, and cache entries will be written back to the cache at the end of the job after all Gradle executions have been completed.
### Disabling caching ### Disabling caching
@@ -120,7 +125,7 @@ By default, The `setup-gradle` action will only write to the cache from Jobs on
Jobs on other branches will read entries from the cache but will not write updated entries. Jobs on other branches will read entries from the cache but will not write updated entries.
See [Optimizing cache effectiveness](#select-which-branches-should-write-to-the-cache) for a more detailed explanation. See [Optimizing cache effectiveness](#select-which-branches-should-write-to-the-cache) for a more detailed explanation.
In some circumstances it makes sense to change this default, and to configure a workflow Job to read existing cache entries but not to write changes back. In some circumstances, it makes sense to change this default and configure a workflow Job to read existing cache entries but not to write changes back.
You can configure read-only caching for `setup-gradle` as follows: You can configure read-only caching for `setup-gradle` as follows:
@@ -138,7 +143,7 @@ cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/head
### Using the cache write-only ### Using the cache write-only
In certain circumstances it may be desirable to start with a clean Gradle User Home state, but to save that state at the end of a workflow Job: In certain circumstances it may be desirable to start with a clean Gradle User Home state, but to save the state at the end of a workflow Job:
```yaml ```yaml
cache-write-only: true cache-write-only: true
@@ -149,10 +154,10 @@ cache-write-only: true
When the action detects that the Gradle User Home caches directory already exists (`~/.gradle/caches`), then by default it will not overwrite the existing content of this directory. When the action detects that the Gradle User Home caches directory already exists (`~/.gradle/caches`), then by default it will not overwrite the existing content of this directory.
This can occur when a prior action initializes this directory, or when using a self-hosted runner that retains this directory between uses. This can occur when a prior action initializes this directory, or when using a self-hosted runner that retains this directory between uses.
In this case the Job Summary will display a message like: In this case, the Job Summary will display a message like:
> Caching for Gradle actions was disabled due to pre-existing Gradle User Home > Caching for Gradle actions was disabled due to pre-existing Gradle User Home
If you want override the default and have The `setup-gradle` action caches overwrite existing content in the Gradle User Home, you can set the `cache-overwrite-existing` parameter to 'true': If you want to override the default and have the caches of the `setup-gradle` action overwrite existing content in the Gradle User Home, you can set the `cache-overwrite-existing` parameter to `true`:
```yaml ```yaml
cache-overwrite-existing: true cache-overwrite-existing: true
@@ -162,12 +167,12 @@ cache-overwrite-existing: true
When Gradle is executed with the [configuration-cache](https://docs.gradle.org/current/userguide/configuration_cache.html) enabled, the configuration-cache data is stored When Gradle is executed with the [configuration-cache](https://docs.gradle.org/current/userguide/configuration_cache.html) enabled, the configuration-cache data is stored
in the project directory, at `<project-dir>/.gradle/configuration-cache`. Due to the way the configuration-cache works, [this file may contain stored credentials and other in the project directory, at `<project-dir>/.gradle/configuration-cache`. Due to the way the configuration-cache works, [this file may contain stored credentials and other
secrets](https://docs.gradle.org/release-nightly/userguide/configuration_cache.html#config_cache:secrets), and this data needs to be encrypted in order to be safely stored in the GitHub Actions cache. secrets](https://docs.gradle.org/release-nightly/userguide/configuration_cache.html#config_cache:secrets), and this data needs to be encrypted to be safely stored in the GitHub Actions cache.
In order to benefit from configuration caching in your GitHub Actions workflow, you must: To benefit from configuration caching in your GitHub Actions workflow, you must:
- Execute your build with Gradle 8.6 or newer. This can be achieved directly, or via the Gradle Wrapper. - Execute your build with Gradle 8.6 or newer. This can be achieved directly or via the Gradle Wrapper.
- Enable the configuration cache for your build. - Enable the configuration cache for your build.
- Generate a [valid Gradle encryption key](https://docs.gradle.org/8.6-rc-1/userguide/configuration_cache.html#config_cache:secrets:configuring_encryption_key) and save it as a [GitHub Actions secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions). - Generate a [valid Gradle encryption key](https://docs.gradle.org/8.6/userguide/configuration_cache.html#config_cache:secrets:configuring_encryption_key) and save it as a [GitHub Actions secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions).
- Provide the secret key via the `cache-encryption-key` action parameter. - Provide the secret key via the `cache-encryption-key` action parameter.
```yaml ```yaml
@@ -178,7 +183,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: gradle/actions/setup-gradle@v3 - uses: gradle/actions/setup-gradle@v3
with: with:
gradle-version: 8.6-rc-1 gradle-version: 8.6
cache-encryption-key: ${{ secrets.GradleEncryptionKey }} cache-encryption-key: ${{ secrets.GradleEncryptionKey }}
- run: gradle build --configuration-cache - run: gradle build --configuration-cache
``` ```
@@ -193,20 +198,6 @@ Specifically:
Using either of these mechanisms may interfere with the caching provided by this action. If you choose to use a different mechanism to save and restore the Gradle User Home, you should disable the caching provided by this action, as described above. Using either of these mechanisms may interfere with the caching provided by this action. If you choose to use a different mechanism to save and restore the Gradle User Home, you should disable the caching provided by this action, as described above.
### Cache debugging and analysis
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 insight into how much cache space is being used.
It is possible to enable additional debug logging for cache operations. You do via the `GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED` environment variable:
```yaml
env:
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
```
Note that this setting will also prevent certain cache operations from running in parallel, further assisting with debugging.
## How Gradle User Home caching works ## How Gradle User Home caching works
### Properties of the GitHub Actions cache ### Properties of the GitHub Actions cache
@@ -220,17 +211,17 @@ Each of these properties has influenced the design and implementation of the cac
### Which content is cached ### Which content is cached
Using experiments and observations, we have attempted to identify which Gradle User Home content is worth saving and restoring between build invocations. We considered both the respective size of the content and the impact this content has on build times. As well as the obvious candidates like downloaded dependencies, we saw that compiled build scripts, transformed Jar files and other content can also have a significant impact. Using experiments and observations, we have attempted to identify which Gradle User Home content is worth saving and restoring between build invocations. We considered both the respective size of the content and the impact this content has on build times. As well as the obvious candidates like downloaded dependencies, we saw that compiled build scripts, transformed Jar files, and other content can also have a significant impact.
In the end, we opted to save and restore as much content as is practical, including: In the end, we opted to save and restore as much content as is practical, including:
- `caches/<version>/generated-gradle-jars`: These files are generated on first use of a particular Gradle version, and are expensive to recreate - `caches/<version>/generated-gradle-jars`: These files are generated on the first use of a particular Gradle version, and are expensive to recreate
- `caches/<version>/kotlin-dsl` and `caches/<version>/scripts`: These are the compiled build scripts. The Kotlin ones in particular can benefit from caching. - `caches/<version>/kotlin-dsl` and `caches/<version>/scripts`: These are the compiled build scripts. The Kotlin ones in particular can benefit from caching.
- `caches/modules-2`: The downloaded dependencies - `caches/modules-2`: The downloaded dependencies
- `caches/transforms-3`: The results of artifact transforms - `caches/transforms-3`: The results of artifact transforms
- `caches/jars-9`: Jar files that have been processed/instrumented by Gradle - `caches/jars-9`: Jar files that have been processed/instrumented by Gradle
- `caches/build-cache-1`: The local build cache - `caches/build-cache-1`: The local build cache
In certain cases a particular section of Gradle User Home will be too large to make caching effective. In these cases, particular subdirectories can be excluded from caching. See [Exclude content from Gradle User Home cache](#exclude-content-from-gradle-user-home-cache). In certain cases, a particular section of Gradle User Home will be too large to make caching effective. In these cases, particular subdirectories can be excluded from caching. See [Exclude content from Gradle User Home cache](#exclude-content-from-gradle-user-home-cache).
### Cache keys ### Cache keys
@@ -257,18 +248,18 @@ This allows the most recent state to always be available in the GitHub actions c
### Finding a matching cache entry ### Finding a matching cache entry
In most cases, no exact match will exist for the cache key. Instead, the Gradle User Home will be restored for the closest matching cache entry, using a set of "restore keys". The entries will be matched with the following precedence: In most cases, no exact match will exist for the cache key. Instead, the Gradle User Home will be restored for the closest matching cache entry, using a set of "restore keys". The entries will be matched with the following precedence:
- An exact match on OS, job id, workflow name, matrix and Git SHA - An exact match on OS, job id, workflow name, matrix, and Git SHA
- The most recent entry saved for the same OS, job id, workflow name and matrix values - The most recent entry saved for the same OS, job id, workflow name, and matrix values
- The most recent entry saved for the same OS and job id - The most recent entry saved for the same OS and job id
- The most recent entry saved for the same OS - The most recent entry saved for the same OS
Due to branch scoping of cache entries, the above match will be first performed for entries from the same branch, and then for the default ('main') branch. Due to branch scoping of cache entries, the above match will be first performed for entries from the same branch, and then for the default ('main') branch.
After the Job is complete, the current Gradle User Home state will be collected and written as a new cache entry with the complete cache key. Old entries will be expunged from the GitHub Actions cache on a least-recently-used basis. After the Job is complete, the current Gradle User Home state will be collected and written as a new cache entry with the complete cache key. Old entries will be expunged from the GitHub Actions cache on a least recently used basis.
Note that while effective, this mechanism is not inherently efficient. It requires the entire Gradle User Home directory to be stored separately for each branch, for every OS+Job+Matrix combination. In addition, a new cache entry to be written on every GitHub Actions run. Note that while effective, this mechanism is not inherently efficient. It requires the entire Gradle User Home directory to be stored separately for each branch, for every OS+Job+Matrix combination. In addition, it writes a new cache entry on every GitHub Actions run.
This inefficiency is effectively mitigated by [Deduplication of Gradle User Home cache entries](#deduplication-of-gradle-user-home-cache-entries), and can be further optimized for a workflow using the techniques described in [Optimizing cache effectiveness](#optimizing-cache-effectiveness). This inefficiency is effectively mitigated by [Deduplication of Gradle User Home cache entries](#deduplication-of-gradle-user-home-cache-entries) and can be further optimized for a workflow using the techniques described in [Optimizing cache effectiveness](#optimizing-cache-effectiveness).
### Deduplication of Gradle User Home cache entries ### Deduplication of Gradle User Home cache entries
@@ -284,7 +275,7 @@ For example, this means that all jobs executing a particular version of the Grad
### Stopping the Gradle daemon ### 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. By default, the action will stop all running Gradle daemons in the post-action step, before saving the Gradle User Home state.
This allows for any Gradle User Home cleanup to occur, and avoid file-locking issues on Windows. This allows for any Gradle User Home cleanup to occur, and avoid file-locking issues on Windows.
If caching is disabled or the cache is in read-only mode, the daemon will not be stopped and will continue running after the job is completed. If caching is disabled or the cache is in read-only mode, the daemon will not be stopped and will continue running after the job is completed.
@@ -294,7 +285,7 @@ If caching is disabled or the cache is in read-only mode, the daemon will not be
Cache storage space for GitHub actions is limited, and writing new cache entries can trigger the deletion of existing 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 `setup-gradle` steps. Eviction of shared cache entries can reduce cache effectiveness, slowing down your `setup-gradle` steps.
There are a number of actions you can take if your cache use is less effective due to entry eviction. There are a several actions you can take if your cache use is less effective due to entry eviction.
At the end of a Job, The `setup-gradle` action will write a summary of the Gradle builds executed, together with a detailed report of the cache entries that were read and written during the Job. This report can provide valuable insights that may help to determine the right way to optimize the cache usage for your workflow. At the end of a Job, The `setup-gradle` action will write a summary of the Gradle builds executed, together with a detailed report of the cache entries that were read and written during the Job. This report can provide valuable insights that may help to determine the right way to optimize the cache usage for your workflow.
@@ -302,23 +293,23 @@ At the end of a Job, The `setup-gradle` action will write a summary of the Gradl
Consider a workflow that first runs a Job "compile-and-unit-test" to compile the code and run some basic unit tests, which is followed by a matrix of parallel "integration-test" jobs that each run a set of integration tests for the repository. Each "integration test" Job requires all of the dependencies required by "compile-and-unit-test", and possibly one or 2 additional dependencies. Consider a workflow that first runs a Job "compile-and-unit-test" to compile the code and run some basic unit tests, which is followed by a matrix of parallel "integration-test" jobs that each run a set of integration tests for the repository. Each "integration test" Job requires all of the dependencies required by "compile-and-unit-test", and possibly one or 2 additional dependencies.
By default, a new cache entry will be written on completion of each integration test job. If no additional dependencies were downloaded then this cache entry will share the "dependencies" entry with the "compile-and-unit-test" job, but if a single dependency was downloaded then an entire new "dependencies" entry would be written. (The `setup-gradle` action does not _yet_ support a layered cache that could do this more efficiently). If each of these "integration-test" entries with their different "dependencies" entries is too large, then it could result in other important entries being evicted from the GitHub Actions cache. By default, a new cache entry will be written on completion of each integration test job. If no additional dependencies were downloaded then this cache entry will share the "dependencies" entry with the "compile-and-unit-test" job, but if a single dependency was downloaded then an entirely new "dependencies" entry would be written. (The `setup-gradle` action does not _yet_ support a layered cache that could do this more efficiently). If each of these "integration-test" entries with their different "dependencies" entries is too large, then it could result in other important entries being evicted from the GitHub Actions cache.
There are some techniques that can be used to avoid/mitigate this issue: Some techniques can be used to avoid/mitigate this issue:
- Configure the "integration-test" jobs with `cache-read-only: true`, meaning that the Job will use the entry written by the "compile-and-unit-test" job. This will avoid the overhead of cache entries for each of these jobs, at the expense of re-downloading any additional dependencies required by "integration-test". - Configure the "integration-test" jobs with `cache-read-only: true`, meaning that the Job will use the entry written by the "compile-and-unit-test" job. This will avoid the overhead of cache entries for each of these jobs, at the expense of re-downloading any additional dependencies required by "integration-test".
- Add an additional step to the "compile-and-unit-test" job which downloads all dependencies required by the integration-test jobs but does not execute the tests. This will allow the "dependencies" entry for "compile-and-unit-test" to be shared among all cache entries for "integration-test". The resulting "integration-test" entries should be much smaller, reducing the potential for eviction. - Add a step to the "compile-and-unit-test" job which downloads all dependencies required by the integration-test jobs but does not execute the tests. This will allow the "dependencies" entry for "compile-and-unit-test" to be shared among all cache entries for "integration-test". The resulting "integration-test" entries should be much smaller, reducing the potential for eviction.
- Combine the above 2 techniques, so that no cache entry is written by "integration-test" jobs, but all required dependencies are already present from the restored "compile-and-unit-test" entry. - Combine the above 2 techniques, so that no cache entry is written by "integration-test" jobs, but all required dependencies are already present from the restored "compile-and-unit-test" entry.
### Select which branches should write to the cache ### Select which branches should write to the cache
GitHub cache entries are not shared between builds on different branches. GitHub cache entries are not shared between builds on different branches.
Workflow runs can restore caches created in either the current branch or the default branch (usually main). Workflow runs can restore caches created in either the current branch or the default branch (usually main).
This means that each branch will have it's own Gradle User Home cache scope, and will not benefit from cache entries written for other (non-default) branches. This means that each branch will have its own Gradle User Home cache scope, and will not benefit from cache entries written for other (non-default) branches.
By default, The `setup-gradle` action will only _write_ to the cache for builds run on the default (`master`/`main`) branch. By default, The `setup-gradle` 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 behavior. Jobs running on other branches will only read from the cache. In most cases, this is the desired behavior.
This is because Jobs run on other branches will benefit from the cache Gradle User Home from `main`, This is because Jobs running on other branches will benefit from the cached Gradle User Home from `main`,
without writing private cache entries that which could lead to evicting these shared entries. without writing private cache entries which could lead to evicting these shared entries.
If you have other long-lived development branches that would benefit from writing to the cache, If you have other long-lived development branches that would benefit from writing to the cache,
you can configure this by disabling the `cache-read-only` action parameter for these branches. you can configure this by disabling the `cache-read-only` action parameter for these branches.
@@ -328,14 +319,13 @@ Note there are some cases where writing cache entries is typically unhelpful (th
- For `pull_request` triggered runs, the cache scope is limited to the merge ref (`refs/pull/.../merge`) and can only be restored by re-runs of the same pull request. - For `pull_request` triggered runs, the cache scope is limited to the merge ref (`refs/pull/.../merge`) and can only be restored by re-runs of the same pull request.
- For `merge_group` triggered runs, the cache scope is limited to a temporary branch with a special prefix created to validate pull request changes, and won't be available on subsequent Merge Queue executions. - For `merge_group` triggered runs, the cache scope is limited to a temporary branch with a special prefix created to validate pull request changes, and won't be available on subsequent Merge Queue executions.
### Exclude content from Gradle User Home cache ### Exclude content from Gradle User Home cache
As well as any wrapper distributions, the action will attempt to save and restore the `caches` and `notifications` directories from Gradle User Home. As well as any wrapper distributions, the action will attempt to save and restore the `caches` and `notifications` directories from Gradle User Home.
Each build is different, and some builds produce more Gradle User Home content than others. Each build is different, and some builds produce more Gradle User Home content than others.
[Cache debugging ](#cache-debugging-and-analysis) can provide insight into which cache entries are the largest, [Cache debugging ](#cache-debugging-and-analysis) can provide insight into which cache entries are the largest,
and the contents to be cached can be fine tuned by including and excluding certain paths within Gradle User Home. and the contents to be cached can be fine-tuned by including and excluding certain paths within the Gradle User Home.
```yaml ```yaml
# Cache downloaded JDKs in addition to the default directories. # Cache downloaded JDKs in addition to the default directories.
@@ -352,25 +342,52 @@ gradle-home-cache-excludes: |
You can specify any number of fixed paths or patterns to include or exclude. You can specify any number of fixed paths or patterns to include or exclude.
File pattern support is documented at https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#patterns-to-match-file-paths. File pattern support is documented at https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#patterns-to-match-file-paths.
### Remove unused files from Gradle User Home before saving to cache ### Remove unused files from Gradle User Home before saving to the cache
The Gradle User Home directory has a tendency to grow over time. When you switch to a new Gradle wrapper version or upgrade a dependency version The Gradle User Home directory tends to grow over time. When you switch to a new Gradle wrapper version or upgrade a dependency version
the old files are not automatically and immediately removed. While this can make sense in a local environment, in a GitHub Actions environment the old files are not automatically and immediately removed. While this can make sense in a local environment, in a GitHub Actions environment
it can lead to ever-larger Gradle User Home cache entries being saved and restored. it can lead to ever-larger Gradle User Home cache entries being saved and restored.
In order to avoid this situation, The `setup-gradle` action supports the `gradle-home-cache-cleanup` parameter. To avoid this situation, The `setup-gradle` action supports the `gradle-home-cache-cleanup` parameter.
When enabled, this feature will attempt to delete any files in the Gradle User Home that were not used by Gradle during the GitHub Actions workflow, When enabled, this feature will attempt to delete any files in the Gradle User Home that were not used by Gradle during the GitHub Actions Workflow, before saving the Gradle User Home to the GitHub Actions cache.
prior to saving the Gradle User Home to the GitHub Actions cache.
Gradle Home cache cleanup is considered experimental and is disabled by default. You can enable this feature for the action as follows: Gradle Home cache cleanup is considered experimental and is disabled by default. You can enable this feature for the action as follows:
```yaml ```yaml
gradle-home-cache-cleanup: true gradle-home-cache-cleanup: true
``` ```
## Debugging and Troubleshooting
To debug a failed job, it can be useful to run with [debug logging enabled](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging).
You can enable debug logging either by:
1. Adding an `ACTIONS_STEP_DEBUG` variable to your repository configuration ([see here](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging#enabling-step-debug-logging)).
2. By re-running a Job and checking the "Enable debug logging" box ([see here](https://github.blog/changelog/2022-05-24-github-actions-re-run-jobs-with-debug-logging/)).
### Increased logging from Gradle builds
When debug logging is enabled, this action will cause all builds to run with the `--info` and `--stacktrace` options.
This is done by inserting the relevant [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties)
at the top of the `${GRADLE_USER_HOME}/gradle.properties` file.
If the additional Gradle logging produced is problematic, you may opt out of this behavior by setting these properties manually in your project `gradle.properties` file:
```properties
# default lifecycle
org.gradle.logging.level=lifecycle
org.gradle.logging.stacktrace=internal
```
### Cache debugging and analysis
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 insight into how much cache space is being used.
When debug logging is enabled, more detailed logging of cache operations is included in the GitHub actions log.
This includes a breakdown of the contents of the Gradle User Home directory, which may assist in cache optimization.
## Build reporting ## Build reporting
The `setup-gradle` action collects information about any Gradle executions that occur in a workflow, including the root project, The `setup-gradle` action collects information about any Gradle executions that occur in a workflow, including the root project,
requested tasks, build outcome and any Build Scan link generated. Details of cache entries read and written are also collected. requested tasks, build outcome, and any Build Scan link generated. Details of cache entries read and written are also collected.
These details are compiled into a Job Summary, which is visible in the GitHub Actions UI. These details are compiled into a Job Summary, which is visible in the GitHub Actions UI.
Generation of a Job Summary is enabled by default for all Jobs using The `setup-gradle` action. This feature can be configured Generation of a Job Summary is enabled by default for all Jobs using The `setup-gradle` action. This feature can be configured
@@ -382,7 +399,7 @@ add-job-summary: 'on-failure' # Valid values are 'always' (default), 'never', an
### Adding Job Summary as a Pull Request comment ### Adding Job Summary as a Pull Request comment
It is sometimes more convenient to view the results of a GitHub Actions Job directly from the Pull Request that triggered It is sometimes more convenient to view the results of a GitHub Actions Job directly from the Pull Request that triggered
the Job. For this purpose you can configure the action so that Job Summary data is added as a Pull Request comment. the Job. For this purpose, you can configure the action so that Job Summary data is added as a Pull Request comment.
```yaml ```yaml
@@ -406,13 +423,13 @@ jobs:
- run: ./gradlew build --scan - run: ./gradlew build --scan
``` ```
Note that in order to add a Pull Request comment, the workflow must be configured with the `pull-requests: write` permission. Note that to add a Pull Request comment, the workflow must be configured with the `pull-requests: write` permission.
### Build Scan® link as Step output ### Build Scan® link as Step output
As well as reporting all [Build Scan](https://gradle.com/build-scans/) links in the Job Summary, As well as reporting all [Build Scan](https://gradle.com/build-scans/) links in the Job Summary,
The `setup-gradle` action action makes this link available an an output of any Step that executes Gradle. The `setup-gradle` action makes this link available as an output of any Step that executes Gradle.
The output name is `build-scan-url`. You can then use the build scan link in subsequent actions of your workflow. The output name is `build-scan-url`. You can then use the build scan link in subsequent actions of your workflow.
@@ -448,16 +465,16 @@ jobs:
Note that the action collects information about Gradle invocations via an [Initialization Script](https://docs.gradle.org/current/userguide/init_scripts.html#sec:using_an_init_script) Note that the action collects information about Gradle invocations via an [Initialization Script](https://docs.gradle.org/current/userguide/init_scripts.html#sec:using_an_init_script)
located at `USER_HOME/.gradle/init.d/gradle-actions.build-result-capture.init.gradle`. located at `USER_HOME/.gradle/init.d/gradle-actions.build-result-capture.init.gradle`.
If you are adding any custom init scripts to the `USER_HOME/.gradle/init.d` directory, it may be necessary to ensure these files are applied prior to `gradle-actions.build-result-capture.init.gradle`. If you are adding any custom init scripts to the `USER_HOME/.gradle/init.d` directory, it may be necessary to ensure these files are applied before `gradle-actions.build-result-capture.init.gradle`.
Since Gradle applies init scripts in alphabetical order, one way to ensure this is via file naming. Since Gradle applies init scripts in alphabetical order, one way to ensure this is via file naming.
## Support for GitHub Enterprise Server (GHES) ## Support for GitHub Enterprise Server (GHES)
You can use The `setup-gradle` action on GitHub Enterprise Server, and benefit from the improved integration with Gradle. Depending on the version of GHES you are running, certain features may be limited: You can use the `setup-gradle` action on GitHub Enterprise Server, and benefit from the improved integration with Gradle. Depending on the version of GHES you are running, certain features may be limited:
- Build Scan links are captured and displayed in the GitHub Actions UI - Build Scan links are captured and displayed in the GitHub Actions UI
- Easily run your build with different versions of Gradle - Easily run your build with different versions of Gradle
- Save/restore of Gradle User Home (requires GHES v3.5+ : GitHub Actions cache was introduced in GHES 3.5) - Save/restore of Gradle User Home (requires GHES v3.5+ : GitHub Actions cache was introduced in GHES 3.5)
- Support for GitHub Actions Job Summary (requires GHES 3.6+ : GitHub Actions Job Summary support was introduced in GHES 3.6). In earlier versions of GHES the build-results summary and caching report will be written to the workflow log, as part of the post-action step. - Support for GitHub Actions Job Summary (requires GHES 3.6+ : GitHub Actions Job Summary support was introduced in GHES 3.6). In earlier versions of GHES, the build-results summary and caching report will be written to the workflow log, as part of the post-action step.
## GitHub Dependency Graph support ## GitHub Dependency Graph support
@@ -471,7 +488,7 @@ You can use The `setup-gradle` action on GitHub Enterprise Server, and benefit f
The `setup-gradle` action has support for submitting a [GitHub Dependency Graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph) snapshot via the [GitHub Dependency Submission API](https://docs.github.com/en/rest/dependency-graph/dependency-submission?apiVersion=2022-11-28). The `setup-gradle` action has support for submitting a [GitHub Dependency Graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph) snapshot via the [GitHub Dependency Submission API](https://docs.github.com/en/rest/dependency-graph/dependency-submission?apiVersion=2022-11-28).
The dependency graph snapshot is generated via integration with the [GitHub Dependency Graph Gradle Plugin](https://plugins.gradle.org/plugin/org.gradle.github-dependency-graph-gradle-plugin), and saved as a workflow artifact. The generated snapshot files can be submitted either in the same job, or in a subsequent job (in the same or a dependent workflow). The dependency graph snapshot is generated via integration with the [GitHub Dependency Graph Gradle Plugin](https://plugins.gradle.org/plugin/org.gradle.github-dependency-graph-gradle-plugin) and saved as a workflow artifact. The generated snapshot files can be submitted either in the same job or in a subsequent job (in the same or a dependent workflow).
The generated dependency graph snapshot reports all of the dependencies that were resolved during a build execution, and is used by GitHub to generate [Dependabot Alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts) for vulnerable dependencies, as well as to populate the [Dependency Graph insights view](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#viewing-the-dependency-graph). The generated dependency graph snapshot reports all of the dependencies that were resolved during a build execution, and is used by GitHub to generate [Dependabot Alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts) for vulnerable dependencies, as well as to populate the [Dependency Graph insights view](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#viewing-the-dependency-graph).
@@ -484,8 +501,8 @@ You enable GitHub Dependency Graph support by setting the `dependency-graph` act
| `disabled` | Do not generate a dependency graph for any build invocations.<p>This is the default. | | `disabled` | Do not generate a dependency graph for any build invocations.<p>This is the default. |
| `generate` | Generate a dependency graph snapshot for each build invocation. | | `generate` | Generate a dependency graph snapshot for each build invocation. |
| `generate-and-submit` | Generate a dependency graph snapshot for each build invocation, and submit these via the Dependency Submission API on completion of the job. | | `generate-and-submit` | Generate a dependency graph snapshot for each build invocation, and submit these via the Dependency Submission API on completion of the job. |
| `generate-and-upload` | Generate a dependency graph snapshot for each build invocation, saving as a workflow artifact. | | `generate-and-upload` | Generate a dependency graph snapshot for each build invocation, saving it as a workflow artifact. |
| `download-and-submit` | Download any previously saved dependency graph snapshots, and submit them via the Dependency Submission API. This can be useful to submit [dependency graphs for pull requests submitted from a repository forks](#dependency-graphs-for-pull-request-workflows). | | `download-and-submit` | Download any previously saved dependency graph snapshots, and submit them via the Dependency Submission API. This can be useful to submit [dependency graphs for pull requests submitted from repository forks](#dependency-graphs-for-pull-request-workflows). |
Example of a CI workflow that generates and submits a dependency graph: Example of a CI workflow that generates and submits a dependency graph:
```yaml ```yaml
@@ -509,7 +526,7 @@ jobs:
run: ./gradlew build run: ./gradlew build
``` ```
The `contents: write` permission is required in order to submit (but not generate) the dependency graph file. The `contents: write` permission is required to submit (but not generate) the dependency graph file.
Depending on [repository settings](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token), this permission may be available by default or may need to be explicitly enabled in the workflow file (as above). Depending on [repository settings](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token), this permission may be available by default or may need to be explicitly enabled in the workflow file (as above).
> [!IMPORTANT] > [!IMPORTANT]
@@ -524,8 +541,8 @@ Depending on [repository settings](https://docs.github.com/en/actions/security-g
By default, if a failure is encountered when generating or submitting the dependency graph, the action will log the failure as a warning and continue. By default, if a failure is encountered when generating or submitting the dependency graph, the action will log the failure as a warning and continue.
This allows your workflow to be resilient to dependency graph failures, in case dependency graph production is a side-effect rather than the primary purpose of a workflow. This allows your workflow to be resilient to dependency graph failures, in case dependency graph production is a side-effect rather than the primary purpose of a workflow.
If instead you have a workflow that has a primary purpose to generate and submit a dependency graph, then it makes sense for this workflow to fail if the dependency If instead, you have a workflow whose primary purpose is to generate and submit a dependency graph, it makes sense for this workflow to fail if the dependency
graph cannot be generated or submitted. You can enable this behaviour with the `dependency-graph-continue-on-failure` parameter, which defaults to `true`. graph cannot be generated or submitted. You can enable this behavior with the `dependency-graph-continue-on-failure` parameter, which defaults to `true`.
```yaml ```yaml
# Ensure that the workflow Job will fail if the dependency graph cannot be submitted # Ensure that the workflow Job will fail if the dependency graph cannot be submitted
@@ -538,7 +555,9 @@ graph cannot be generated or submitted. You can enable this behaviour with the `
### Using a custom plugin repository ### Using a custom plugin repository
By default, the action downloads the `github-dependency-graph-gradle-plugin` from the Gradle Plugin Portal (https://plugins.gradle.org). If your GitHub Actions environment does not have access to this URL, you can specify a custom plugin repository to use. By default, the action downloads the `github-dependency-graph-gradle-plugin` from the Gradle Plugin Portal (https://plugins.gradle.org). If your GitHub Actions environment does not have access to this URL, you can specify a custom plugin repository to use.
Do so by setting the `GRADLE_PLUGIN_REPOSITORY_URL` environment variable with your Gradle invocation. Do so by setting the `GRADLE_PLUGIN_REPOSITORY_URL` environment variable with your Gradle invocation.
The `GRADLE_PLUGIN_REPOSITORY_USERNAME` and `GRADLE_PLUGIN_REPOSITORY_PASSWORD` can be used when the plugin repository requires authentication.
```yaml ```yaml
jobs: jobs:
@@ -554,6 +573,10 @@ jobs:
run: ./gradlew build run: ./gradlew build
env: env:
GRADLE_PLUGIN_REPOSITORY_URL: "https://gradle-plugins-proxy.mycorp.com" GRADLE_PLUGIN_REPOSITORY_URL: "https://gradle-plugins-proxy.mycorp.com"
# Set the following variables if your custom plugin repository requires authentication
# GRADLE_PLUGIN_REPOSITORY_USERNAME: "username"
# GRADLE_PLUGIN_REPOSITORY_PASSWORD: ${secrets.MY_REPOSITORY_PASSWORD}
``` ```
### Choosing which Gradle invocations will generate a dependency graph ### Choosing which Gradle invocations will generate a dependency graph
@@ -592,14 +615,14 @@ See the documentation for [dependency-submission](../dependency-submission/READM
Dependency-graph generation is compatible with most versions of Gradle >= `5.2`, and is tested regularly against Dependency-graph generation is compatible with most versions of Gradle >= `5.2`, and is tested regularly against
Gradle versions `5.2.1`, `5.6.4`, `6.0.1`, `6.9.4`, `7.1.1` and `7.6.3`, as well as all patched versions of Gradle 8.x. Gradle versions `5.2.1`, `5.6.4`, `6.0.1`, `6.9.4`, `7.1.1` and `7.6.3`, as well as all patched versions of Gradle 8.x.
A known exception to this is that Gradle `7.0`, `7.0.1` and `7.0.2` are not supported. A known exception to this is that Gradle `7.0`, `7.0.1`, and `7.0.2` are not supported.
See [here](https://github.com/gradle/github-dependency-graph-gradle-plugin?tab=readme-ov-file#gradle-compatibility) for complete compatibility information. See [here](https://github.com/gradle/github-dependency-graph-gradle-plugin?tab=readme-ov-file#gradle-compatibility) for complete compatibility information.
### Reducing storage costs for saved dependency graph artifacts ### Reducing storage costs for saved dependency graph artifacts
When `generate` or `generate-and-submit` is used with the action, the dependency graph that is generated is stored as a workflow artifact. When `generate` or `generate-and-submit` is used with the action, the dependency graph that is generated is stored as a workflow artifact.
By default, these artifacts are retained for a period of 30 days (or as configured for the repository). By default, these artifacts are retained for 30 days (or as configured for the repository).
To reduce storage costs for these artifacts, you can set the `artifact-retention-days` value to a lower number. To reduce storage costs for these artifacts, you can set the `artifact-retention-days` value to a lower number.
```yaml ```yaml
@@ -620,7 +643,7 @@ The same auto-injection behavior is available for the Common Custom User Data Gr
## Enabling Develocity injection ## Enabling Develocity injection
In order to enable Develocity injection for your build, you must provide the required configuration via environment variables. To enable Develocity injection for your build, you must provide the required configuration via environment variables.
Here's a minimal example: Here's a minimal example:
@@ -630,7 +653,7 @@ name: Run build with Develocity injection
env: env:
DEVELOCITY_INJECTION_ENABLED: true DEVELOCITY_INJECTION_ENABLED: true
DEVELOCITY_URL: https://develocity.your-server.com DEVELOCITY_URL: https://develocity.your-server.com
DEVELOCITY_PLUGIN_VERSION: 3.16.2 DEVELOCITY_PLUGIN_VERSION: 3.17
jobs: jobs:
build: build:
@@ -643,32 +666,35 @@ jobs:
run: ./gradlew build run: ./gradlew build
``` ```
This configuration will automatically apply `v3.16.2` of the [Develocity Gradle plugin](https://docs.gradle.com/enterprise/gradle-plugin/), and publish build scans to https://develocity.your-server.com. This configuration will automatically apply `v3.17` of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/), and publish build scans to https://develocity.your-server.com.
This example assumes that the `develocity.your-server.com` server allows anonymous publishing of build scans. This example assumes that the `develocity.your-server.com` server allows anonymous publishing of build scans.
In the likely scenario that your Develocity server requires authentication, you will also need to configure an addition environment variable In the likely scenario that your Develocity server requires authentication, you will also need to configure an additional environment variable
with a valid [Develocity access key](https://docs.gradle.com/enterprise/gradle-plugin/#via_environment_variable). with a valid [Develocity access key](https://docs.gradle.com/develocity/gradle-plugin/#via_environment_variable).
## Configuring Develocity injection ## Configuring Develocity injection
The `init-script` supports a number of additional configuration parameters that you may fine useful. All configuration options (required and optional) are detailed below: The `init-script` supports several additional configuration parameters that you may find useful. All configuration options (required and optional) are detailed below:
| Variable | Required | Description | | Variable | Required | Description |
|-----------------------------------| --- | --- | |--------------------------------------| --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| DEVELOCITY_INJECTION_ENABLED | :white_check_mark: | enables Develocity injection | | DEVELOCITY_INJECTION_ENABLED | :white_check_mark: | enables Develocity injection |
| DEVELOCITY_URL | :white_check_mark: | the URL of the Develocity server | | DEVELOCITY_URL | :white_check_mark: | the URL of the Develocity server |
| DEVELOCITY_ALLOW_UNTRUSTED_SERVER | | allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed certificate | | DEVELOCITY_ALLOW_UNTRUSTED_SERVER | | allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed certificate |
| DEVELOCITY_CAPTURE_FILE_FINGERPRINTS | | enables capturing the paths and content hashes of each individual input file |
| DEVELOCITY_ENFORCE_URL | | enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL | | DEVELOCITY_ENFORCE_URL | | enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL |
| DEVELOCITY_PLUGIN_VERSION | :white_check_mark: | the version of the [Develocity Gradle plugin](https://docs.gradle.com/enterprise/gradle-plugin/) to apply | | DEVELOCITY_PLUGIN_VERSION | :white_check_mark: | the version of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/) to apply |
| DEVELOCITY_CCUD_PLUGIN_VERSION | | the version of the [Common Custom User Data Gradle plugin](https://github.com/gradle/common-custom-user-data-gradle-plugin) to apply, if any | | DEVELOCITY_CCUD_PLUGIN_VERSION | | the version of the [Common Custom User Data Gradle plugin](https://github.com/gradle/common-custom-user-data-gradle-plugin) to apply, if any |
| GRADLE_PLUGIN_REPOSITORY_URL | | the URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default | | GRADLE_PLUGIN_REPOSITORY_URL | | the URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default |
| GRADLE_PLUGIN_REPOSITORY_USERNAME | | the username for the repository URL to use when resolving the Develocity and CCUD plugins |
| GRADLE_PLUGIN_REPOSITORY_PASSWORD | | the password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable |
## Publishing to scans.gradle.com ## Publishing to scans.gradle.com
Develocity injection is designed to enable publishing of build scans to a Develocity instance, Develocity injection is designed to enable the publishing of build scans to a Develocity instance,
but is also useful for publishing to the public Build Scans instance (https://scans.gradle.com). but is also useful for publishing to the public Build Scans instance (https://scans.gradle.com).
To publish to https://scans.gradle.com, you must specify in your workflow that you accept the [Gradle Terms of Service](https://gradle.com/terms-of-service). To publish to https://scans.gradle.com, you must specify in your workflow that you accept the [Gradle Terms of Use](https://gradle.com/help/legal-terms-of-use).
```yaml ```yaml
name: Run build and publish Build Scan name: Run build and publish Build Scan
@@ -682,10 +708,9 @@ jobs:
uses: gradle/actions/setup-gradle@v3 uses: gradle/actions/setup-gradle@v3
with: with:
build-scan-publish: true build-scan-publish: true
build-scan-terms-of-service-url: "https://gradle.com/terms-of-service" build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-service-agree: "yes" build-scan-terms-of-use-agree: "yes"
- name: Run a Gradle build - a build scan will be published automatically - name: Run a Gradle build - a build scan will be published automatically
run: ./gradlew build run: ./gradlew build
``` ```

View File

@@ -85,19 +85,29 @@ inputs:
build-scan-publish: build-scan-publish:
description: | description: |
Set to 'true' to automatically publish build results as a Build Scan on scans.gradle.com. Set to 'true' to automatically publish build results as a Build Scan on scans.gradle.com.
For publication to succeed without user input, you must also provide values for `build-scan-terms-of-service-url` and 'build-scan-terms-of-service-agree'. For publication to succeed without user input, you must also provide values for `build-scan-terms-of-use-url` and 'build-scan-terms-of-use-agree'.
required: false required: false
default: false default: false
build-scan-terms-of-service-url: build-scan-terms-of-use-url:
description: The URL to the Build Scan® terms of service. This input must be set to 'https://gradle.com/terms-of-service'. description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service' or 'https://gradle.com/help/legal-terms-of-use'.
required: false required: false
build-scan-terms-of-service-agree: build-scan-terms-of-use-agree:
description: Indicate that you agree to the Build Scan® terms of service. This input value must be "yes". description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
required: false required: false
# DEPRECATED ACTION INPUTS # DEPRECATED ACTION INPUTS
build-scan-terms-of-service-url:
description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service'.
required: false
deprecation-message: The input has been renamed to align with the Develocity API. Use 'build-scan-terms-of-use-url' instead.
build-scan-terms-of-service-agree:
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
required: false
deprecation-message: The input has been renamed to align with the Develocity API. Use 'build-scan-terms-of-use-agree' instead.
arguments: arguments:
description: Gradle command line arguments (supports multi-line input) description: Gradle command line arguments (supports multi-line input)
required: false required: false

View File

@@ -1,3 +1,3 @@
# Configuration file for asdf version manager # Configuration file for asdf version manager
nodejs 20.10.0 nodejs 20.10.0
gradle 8.5 gradle 8.7

1221
sources/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,35 +28,35 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/artifact": "2.1.0", "@actions/artifact": "2.1.4",
"@actions/cache": "3.2.3", "@actions/cache": "3.2.4",
"@actions/core": "1.10.1", "@actions/core": "1.10.1",
"@actions/exec": "1.1.1", "@actions/exec": "1.1.1",
"@actions/github": "6.0.0", "@actions/github": "6.0.0",
"@actions/glob": "0.4.0", "@actions/glob": "0.4.0",
"@actions/http-client": "2.2.0", "@actions/http-client": "2.2.1",
"@actions/tool-cache": "2.0.1", "@actions/tool-cache": "2.0.1",
"@octokit/rest": "19.0.13", "@octokit/rest": "20.1.0",
"@octokit/webhooks-types": "7.3.1", "@octokit/webhooks-types": "7.5.0",
"semver": "7.5.4", "semver": "7.6.0",
"string-argv": "0.3.2" "string-argv": "0.3.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "29.5.11", "@types/jest": "29.5.12",
"@types/node": "20.10.0", "@types/node": "20.12.4",
"@types/unzipper": "0.10.9", "@types/unzipper": "0.10.9",
"@typescript-eslint/parser": "6.19.1", "@typescript-eslint/parser": "7.5.0",
"@vercel/ncc": "0.38.1", "@vercel/ncc": "0.38.1",
"eslint": "8.56.0", "eslint": "8.57.0",
"eslint-plugin-github": "4.10.1", "eslint-plugin-github": "4.10.2",
"eslint-plugin-jest": "27.6.3", "eslint-plugin-jest": "27.9.0",
"eslint-plugin-prettier": "5.1.3", "eslint-plugin-prettier": "5.1.3",
"jest": "29.7.0", "jest": "29.7.0",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"npm-run-all": "4.1.5", "npm-run-all": "4.1.5",
"patch-package": "8.0.0", "patch-package": "8.0.0",
"prettier": "3.2.4", "prettier": "3.2.5",
"ts-jest": "29.1.2", "ts-jest": "29.1.2",
"typescript": "5.3.3" "typescript": "5.4.3"
} }
} }

View File

@@ -1,26 +1,25 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import { import {getBuildScanPublishEnabled, getBuildScanTermsOfUseUrl, getBuildScanTermsOfUseAgree} from './input-params'
getBuildScanPublishEnabled,
getBuildScanTermsOfServiceUrl,
getBuildScanTermsOfServiceAgree
} from './input-params'
export function setup(): void { export function setup(): void {
if (getBuildScanPublishEnabled() && verifyTermsOfServiceAgreement()) { maybeExportVariable('DEVELOCITY_INJECTION_INIT_SCRIPT_NAME', 'gradle-actions.inject-develocity.init.gradle')
maybeExportVariable('DEVELOCITY_AUTO_INJECTION_CUSTOM_VALUE', 'gradle-actions')
if (getBuildScanPublishEnabled() && verifyTermsOfUseAgreement()) {
maybeExportVariable('DEVELOCITY_INJECTION_ENABLED', 'true') maybeExportVariable('DEVELOCITY_INJECTION_ENABLED', 'true')
maybeExportVariable('DEVELOCITY_PLUGIN_VERSION', '3.16.2') maybeExportVariable('DEVELOCITY_PLUGIN_VERSION', '3.17')
maybeExportVariable('DEVELOCITY_CCUD_PLUGIN_VERSION', '1.12.1') maybeExportVariable('DEVELOCITY_CCUD_PLUGIN_VERSION', '1.13')
maybeExportVariable('BUILD_SCAN_TERMS_OF_SERVICE_URL', getBuildScanTermsOfServiceUrl()) maybeExportVariable('DEVELOCITY_TERMS_OF_USE_URL', getBuildScanTermsOfUseUrl())
maybeExportVariable('BUILD_SCAN_TERMS_OF_SERVICE_AGREE', getBuildScanTermsOfServiceAgree()) maybeExportVariable('DEVELOCITY_TERMS_OF_USE_AGREE', getBuildScanTermsOfUseAgree())
} }
} }
function verifyTermsOfServiceAgreement(): boolean { function verifyTermsOfUseAgreement(): boolean {
if ( if (
getBuildScanTermsOfServiceUrl() !== 'https://gradle.com/terms-of-service' || (getBuildScanTermsOfUseUrl() !== 'https://gradle.com/terms-of-service' &&
getBuildScanTermsOfServiceAgree() !== 'yes' getBuildScanTermsOfUseUrl() !== 'https://gradle.com/help/legal-terms-of-use') ||
getBuildScanTermsOfUseAgree() !== 'yes'
) { ) {
core.warning(`Terms of service must be agreed in order to publish build scans.`) core.warning(`Terms of use must be agreed in order to publish build scans.`)
return false return false
} }
return true return true

View File

@@ -192,6 +192,10 @@ export class GradleStateCache {
// Copy the default toolchain definitions to `~/.m2/toolchains.xml` // Copy the default toolchain definitions to `~/.m2/toolchains.xml`
this.registerToolchains() this.registerToolchains()
if (core.isDebug()) {
this.configureInfoLogLevel()
}
} }
private copyInitScripts(): void { private copyInitScripts(): void {
@@ -241,11 +245,30 @@ export class GradleStateCache {
} }
/** /**
* When cache debugging is enabled, this method will give a detailed report * When the GitHub environment ACTIONS_RUNNER_DEBUG is true, run Gradle with --info and --stacktrace.
* of the Gradle User Home contents. * see https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging
*
* @VisibleForTesting
*/
configureInfoLogLevel(): void {
const infoProperties = `org.gradle.logging.level=info\norg.gradle.logging.stacktrace=all\n`
const propertiesFile = path.resolve(this.gradleUserHome, 'gradle.properties')
if (fs.existsSync(propertiesFile)) {
core.info(`Merged --info and --stacktrace into existing ${propertiesFile} file`)
const existingProperties = fs.readFileSync(propertiesFile, 'utf-8')
fs.writeFileSync(propertiesFile, `${infoProperties}\n${existingProperties}`)
} else {
core.info(`Created a new ${propertiesFile} with --info and --stacktrace`)
fs.writeFileSync(propertiesFile, infoProperties)
}
}
/**
* When cache debugging is enabled (or ACTIONS_STEP_DEBUG is on),
* this method will give a detailed report of the Gradle User Home contents.
*/ */
private async debugReportGradleUserHomeSize(label: string): Promise<void> { private async debugReportGradleUserHomeSize(label: string): Promise<void> {
if (!isCacheDebuggingEnabled()) { if (!isCacheDebuggingEnabled() && !core.isDebug()) {
return return
} }
if (!fs.existsSync(this.gradleUserHome)) { if (!fs.existsSync(this.gradleUserHome)) {

View File

@@ -14,6 +14,7 @@ import {PostActionJobFailure} from './errors'
import { import {
DependencyGraphOption, DependencyGraphOption,
getDependencyGraphContinueOnFailure, getDependencyGraphContinueOnFailure,
getGithubToken,
getJobMatrix, getJobMatrix,
getArtifactRetentionDays getArtifactRetentionDays
} from './input-params' } from './input-params'
@@ -192,10 +193,6 @@ function getOctokit(): InstanceType<typeof GitHub> {
return github.getOctokit(getGithubToken()) return github.getOctokit(getGithubToken())
} }
function getGithubToken(): string {
return core.getInput('github-token', {required: true})
}
function getRelativePathFromWorkspace(file: string): string { function getRelativePathFromWorkspace(file: string): string {
const workspaceDirectory = layout.workspaceDirectory() const workspaceDirectory = layout.workspaceDirectory()
return path.relative(workspaceDirectory, file) return path.relative(workspaceDirectory, file)

View File

@@ -1,3 +1,4 @@
import * as core from '@actions/core'
import * as path from 'path' import * as path from 'path'
import fs from 'fs' import fs from 'fs'
@@ -37,6 +38,9 @@ function verifyIsExecutableScript(toExecute: string): void {
try { try {
fs.accessSync(toExecute, fs.constants.X_OK) fs.accessSync(toExecute, fs.constants.X_OK)
} catch (err) { } catch (err) {
throw new Error(`Gradle script '${toExecute}' is not executable.`) core.warning(
`Gradle wrapper script '${toExecute}' is not executable. Action will set executable permission and continue.`
)
fs.chmodSync(toExecute, '755')
} }
} }

View File

@@ -79,12 +79,23 @@ export function getBuildScanPublishEnabled(): boolean {
return getBooleanInput('build-scan-publish') return getBooleanInput('build-scan-publish')
} }
export function getBuildScanTermsOfServiceUrl(): string { export function getBuildScanTermsOfUseUrl(): string {
return core.getInput('build-scan-terms-of-service-url') return getTermsOfUseProp('build-scan-terms-of-use-url', 'build-scan-terms-of-service-url')
} }
export function getBuildScanTermsOfServiceAgree(): string { export function getBuildScanTermsOfUseAgree(): string {
return core.getInput('build-scan-terms-of-service-agree') return getTermsOfUseProp('build-scan-terms-of-use-agree', 'build-scan-terms-of-service-agree')
}
/**
* TODO @bigdaz: remove the deprecated input property in the next major release of the action
*/
function getTermsOfUseProp(newPropName: string, oldPropName: string): string {
const newProp = core.getInput(newPropName)
if (newProp !== '') {
return newProp
}
return core.getInput(oldPropName)
} }
function parseJobSummaryOption(paramName: string): JobSummaryOption { function parseJobSummaryOption(paramName: string): JobSummaryOption {

View File

@@ -41,7 +41,9 @@ async function addPRComment(jobSummary: string): Promise<void> {
core.info(`Adding Job Summary as comment to PR #${pull_request_number}.`) core.info(`Adding Job Summary as comment to PR #${pull_request_number}.`)
const prComment = `<h3>Job Summary for Gradle</h3> const prComment = `<h3>Job Summary for Gradle</h3>
<h5>${github.context.workflow} :: <em>${github.context.job}</em></h5> <a href="${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}" target="_blank">
<h5>${context.workflow} :: <em>${context.job}</em></h5>
</a>
${jobSummary}` ${jobSummary}`
@@ -94,8 +96,8 @@ function renderSummaryTable(results: BuildResult[]): string {
function renderBuildResultRow(result: BuildResult): string { function renderBuildResultRow(result: BuildResult): string {
return ` return `
<tr> <tr>
<td>${result.rootProjectName}</td> <td>${truncateString(result.rootProjectName, 30)}</td>
<td>${result.requestedTasks}</td> <td>${truncateString(result.requestedTasks, 60)}</td>
<td align='center'>${result.gradleVersion}</td> <td align='center'>${result.gradleVersion}</td>
<td align='center'>${renderOutcome(result)}</td> <td align='center'>${renderOutcome(result)}</td>
<td>${renderBuildScan(result)}</td> <td>${renderBuildScan(result)}</td>
@@ -111,7 +113,7 @@ function renderBuildScan(result: BuildResult): string {
return renderBuildScanBadge( return renderBuildScanBadge(
'PUBLISH_FAILED', 'PUBLISH_FAILED',
'orange', 'orange',
'https://docs.gradle.com/enterprise/gradle-plugin/#troubleshooting' 'https://docs.gradle.com/develocity/gradle-plugin/#troubleshooting'
) )
} }
if (result.buildScanUri) { if (result.buildScanUri) {
@@ -123,7 +125,7 @@ function renderBuildScan(result: BuildResult): string {
function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string { function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string {
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%C2%AE-${outcomeText}-${outcomeColor}?logo=Gradle` const badgeUrl = `https://img.shields.io/badge/Build%20Scan%C2%AE-${outcomeText}-${outcomeColor}?logo=Gradle`
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />` const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>` return `<a href="${targetUrl}" rel="nofollow" target="_blank">${badgeHtml}</a>`
} }
function shouldGenerateJobSummary(buildResults: BuildResult[]): boolean { function shouldGenerateJobSummary(buildResults: BuildResult[]): boolean {
@@ -155,3 +157,11 @@ function shouldAddJobSummary(option: params.JobSummaryOption, buildResults: Buil
return buildResults.some(result => result.buildFailed) return buildResults.some(result => result.buildFailed)
} }
} }
function truncateString(str: string, maxLength: number): string {
if (str.length > maxLength) {
return `<div title='${str}'>${str.slice(0, maxLength - 1)}…</div>`
} else {
return str
}
}

View File

@@ -28,6 +28,9 @@ if (isTopLevelBuild) {
settings.pluginManager.withPlugin("com.gradle.enterprise") { settings.pluginManager.withPlugin("com.gradle.enterprise") {
captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject, invocationId) captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject, invocationId)
} }
settings.pluginManager.withPlugin("com.gradle.develocity") {
captureUsingBuildScanPublished(settings.extensions["develocity"].buildScan, settings.rootProject, invocationId)
}
} }
} else if (atLeastGradle3) { } else if (atLeastGradle3) {
projectsEvaluated { gradle -> projectsEvaluated { gradle ->
@@ -59,7 +62,7 @@ def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId
if (githubOutput) { if (githubOutput) {
new File(githubOutput) << "build-scan-url=${buildScan.buildScanUri}\n" new File(githubOutput) << "build-scan-url=${buildScan.buildScanUri}\n"
} else { } else {
// Retained for compatibility with older GitHub Enterprise versions // Retained for compatibility with older GHES versions
println("::set-output name=build-scan-url::${buildScan.buildScanUri}") println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
} }
} }
@@ -104,7 +107,13 @@ class BuildResults {
} }
def setBuildResult(def result) { def setBuildResult(def result) {
try {
// Gradle and old Build Scan/Gradle Enterprise plugins report a single optional failure in the build result
buildResults['buildFailed'] = result.failure != null buildResults['buildFailed'] = result.failure != null
} catch (Exception e) {
// Develocity plugin unwraps all build failures and reports them as a mandatory array
buildResults['buildFailed'] = !result.failures.empty
}
} }
def setBuildScanUri(def buildScanUrl) { def setBuildScanUri(def buildScanUrl) {

View File

@@ -4,13 +4,29 @@ buildscript {
return System.getProperty(name) ?: System.getenv(envVarName) return System.getProperty(name) ?: System.getenv(envVarName)
} }
def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url') ?: 'https://plugins.gradle.org/m2' def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url') ?: 'https://plugins.gradle.org/m2'
def dependencyGraphPluginVersion = getInputParam('dependency-graph-plugin.version') ?: '1.2.0' def pluginRepositoryUsername = getInputParam('gradle.plugin-repository.username')
def pluginRepositoryPassword = getInputParam('gradle.plugin-repository.password')
def dependencyGraphPluginVersion = getInputParam('dependency-graph-plugin.version') ?: '1.3.0'
logger.lifecycle("Resolving dependency graph plugin ${dependencyGraphPluginVersion} from plugin repository: ${pluginRepositoryUrl}")
repositories { repositories {
maven { url pluginRepositoryUrl } maven {
url pluginRepositoryUrl
if (pluginRepositoryUsername && pluginRepositoryPassword) {
logger.lifecycle("Applying credentials for plugin repository: ${pluginRepositoryUrl}")
credentials {
username(pluginRepositoryUsername)
password(pluginRepositoryPassword)
}
authentication {
basic(BasicAuthentication)
}
}
}
} }
dependencies { dependencies {
classpath "org.gradle:github-dependency-graph-gradle-plugin:${dependencyGraphPluginVersion}" classpath "org.gradle:github-dependency-graph-gradle-plugin:${dependencyGraphPluginVersion}"
} }
} }
apply plugin: org.gradle.github.GitHubDependencyGraphPlugin apply plugin: org.gradle.github.GitHubDependencyGraphPlugin

View File

@@ -2,7 +2,7 @@ import org.gradle.util.GradleVersion
// note that there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated // note that there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated
// conditionally apply the GE / Build Scan plugin to the classpath so it can be applied to the build further down in this script // conditionally apply the Develocity plugin to the classpath so it can be applied to the build further down in this script
initscript { initscript {
def isTopLevelBuild = !gradle.parent def isTopLevelBuild = !gradle.parent
if (!isTopLevelBuild) { if (!isTopLevelBuild) {
@@ -14,6 +14,12 @@ initscript {
return System.getProperty(name) ?: System.getenv(envVarName) return System.getProperty(name) ?: System.getenv(envVarName)
} }
def requestedInitScriptName = getInputParam('develocity.injection.init-script-name')
def initScriptName = buildscript.sourceFile.name
if (requestedInitScriptName != initScriptName) {
return
}
// finish early if injection is disabled // finish early if injection is disabled
def gradleInjectionEnabled = getInputParam("develocity.injection-enabled") def gradleInjectionEnabled = getInputParam("develocity.injection-enabled")
if (gradleInjectionEnabled != "true") { if (gradleInjectionEnabled != "true") {
@@ -21,26 +27,46 @@ initscript {
} }
def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url') def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url')
def gePluginVersion = getInputParam('develocity.plugin.version') def pluginRepositoryUsername = getInputParam('gradle.plugin-repository.username')
def pluginRepositoryPassword = getInputParam('gradle.plugin-repository.password')
def develocityPluginVersion = getInputParam('develocity.plugin.version')
def ccudPluginVersion = getInputParam('develocity.ccud-plugin.version') def ccudPluginVersion = getInputParam('develocity.ccud-plugin.version')
def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0') def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0')
def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0') def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0')
if (gePluginVersion || ccudPluginVersion && atLeastGradle4) { if (develocityPluginVersion || ccudPluginVersion && atLeastGradle4) {
pluginRepositoryUrl = pluginRepositoryUrl ?: 'https://plugins.gradle.org/m2' pluginRepositoryUrl = pluginRepositoryUrl ?: 'https://plugins.gradle.org/m2'
logger.quiet("Develocity plugins resolution: $pluginRepositoryUrl") logger.lifecycle("Develocity plugins resolution: $pluginRepositoryUrl")
repositories { repositories {
maven { url pluginRepositoryUrl } maven {
url pluginRepositoryUrl
if (pluginRepositoryUsername && pluginRepositoryPassword) {
logger.lifecycle("Using credentials for plugin repository")
credentials {
username(pluginRepositoryUsername)
password(pluginRepositoryPassword)
}
authentication {
basic(BasicAuthentication)
}
}
}
} }
} }
dependencies { dependencies {
if (gePluginVersion) { if (develocityPluginVersion) {
classpath atLeastGradle5 ? if (atLeastGradle5) {
"com.gradle:gradle-enterprise-gradle-plugin:$gePluginVersion" : if (GradleVersion.version(develocityPluginVersion) >= GradleVersion.version("3.17")) {
"com.gradle:build-scan-plugin:1.16" classpath "com.gradle:develocity-gradle-plugin:$develocityPluginVersion"
} else {
classpath "com.gradle:gradle-enterprise-gradle-plugin:$develocityPluginVersion"
}
} else {
classpath "com.gradle:build-scan-plugin:1.16"
}
} }
if (ccudPluginVersion && atLeastGradle4) { if (ccudPluginVersion && atLeastGradle4) {
@@ -52,11 +78,17 @@ initscript {
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan' def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin' def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin'
def DEVELOCITY_PLUGIN_ID = 'com.gradle.enterprise' def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise'
def DEVELOCITY_PLUGIN_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin' def GRADLE_ENTERPRISE_PLUGIN_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin'
def DEVELOCITY_EXTENSION_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterpriseExtension' def GRADLE_ENTERPRISE_EXTENSION_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterpriseExtension'
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'
def DEVELOCITY_PLUGIN_CLASS = 'com.gradle.develocity.agent.gradle.DevelocityPlugin'
def DEVELOCITY_CONFIGURATION_CLASS = 'com.gradle.develocity.agent.gradle.DevelocityConfiguration'
def SETTINGS_EXTENSION_CLASSES = [GRADLE_ENTERPRISE_EXTENSION_CLASS, DEVELOCITY_CONFIGURATION_CLASS]
def CI_AUTO_INJECTION_CUSTOM_VALUE_NAME = 'CI auto injection' def CI_AUTO_INJECTION_CUSTOM_VALUE_NAME = 'CI auto injection'
def CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE = 'gradle-actions'
def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin' def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin'
def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin' def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin'
@@ -70,22 +102,40 @@ def getInputParam = { String name ->
return System.getProperty(name) ?: System.getenv(envVarName) return System.getProperty(name) ?: System.getenv(envVarName)
} }
def requestedInitScriptName = getInputParam('develocity.injection.init-script-name')
def initScriptName = buildscript.sourceFile.name
if (requestedInitScriptName != initScriptName) {
logger.quiet("Ignoring init script '${initScriptName}' as requested name '${requestedInitScriptName}' does not match")
return
}
// finish early if injection is disabled // finish early if injection is disabled
def gradleInjectionEnabled = getInputParam("develocity.injection-enabled") def gradleInjectionEnabled = getInputParam("develocity.injection-enabled")
if (gradleInjectionEnabled != "true") { if (gradleInjectionEnabled != "true") {
return return
} }
def geUrl = getInputParam('develocity.url') def develocityUrl = getInputParam('develocity.url')
def geAllowUntrustedServer = Boolean.parseBoolean(getInputParam('develocity.allow-untrusted-server')) def develocityAllowUntrustedServer = Boolean.parseBoolean(getInputParam('develocity.allow-untrusted-server'))
def geEnforceUrl = Boolean.parseBoolean(getInputParam('develocity.enforce-url')) def develocityEnforceUrl = Boolean.parseBoolean(getInputParam('develocity.enforce-url'))
def buildScanUploadInBackground = Boolean.parseBoolean(getInputParam('develocity.build-scan.upload-in-background')) def buildScanUploadInBackground = Boolean.parseBoolean(getInputParam('develocity.build-scan.upload-in-background'))
def gePluginVersion = getInputParam('develocity.plugin.version') def develocityCaptureFileFingerprints = getInputParam('develocity.capture-file-fingerprints') ? Boolean.parseBoolean(getInputParam('develocity.capture-file-fingerprints')) : true
def develocityPluginVersion = getInputParam('develocity.plugin.version')
def ccudPluginVersion = getInputParam('develocity.ccud-plugin.version') def ccudPluginVersion = getInputParam('develocity.ccud-plugin.version')
def buildScanTermsOfServiceUrl = getInputParam('build-scan.terms-of-service.url') def buildScanTermsOfUseUrl = getInputParam('develocity.terms-of-use.url')
def buildScanTermsOfServiceAgree = getInputParam('build-scan.terms-of-service.agree') def buildScanTermsOfUseAgree = getInputParam('develocity.terms-of-use.agree')
def ciAutoInjectionCustomValueValue = getInputParam('develocity.auto-injection.custom-value')
def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0')
def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0') def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0')
def shouldApplyDevelocityPlugin = atLeastGradle5 && develocityPluginVersion && isAtLeast(develocityPluginVersion, '3.17')
def dvOrGe = { def dvValue, def geValue ->
if (shouldApplyDevelocityPlugin) {
return dvValue instanceof Closure<?> ? dvValue() : dvValue
}
return geValue instanceof Closure<?> ? geValue() : geValue
}
// finish early if configuration parameters passed in via system properties are not valid/supported // finish early if configuration parameters passed in via system properties are not valid/supported
if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) { if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) {
@@ -93,42 +143,82 @@ if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) {
return return
} }
// register buildScanPublished listener and optionally apply the GE / Build Scan plugin // register buildScanPublished listener and optionally apply the Develocity plugin
if (GradleVersion.current() < GradleVersion.version('6.0')) { if (GradleVersion.current() < GradleVersion.version('6.0')) {
rootProject { rootProject {
buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming -> buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming ->
def resolutionResult = incoming.resolutionResult def resolutionResult = incoming.resolutionResult
if (gePluginVersion) { if (develocityPluginVersion) {
def scanPluginComponent = resolutionResult.allComponents.find { def scanPluginComponent = resolutionResult.allComponents.find {
it.moduleVersion.with { group == "com.gradle" && (name == "build-scan-plugin" || name == "gradle-enterprise-gradle-plugin") } it.moduleVersion.with { group == "com.gradle" && ['build-scan-plugin', 'gradle-enterprise-gradle-plugin', 'develocity-gradle-plugin'].contains(name) }
} }
if (!scanPluginComponent) { if (!scanPluginComponent) {
logger.quiet("Applying $BUILD_SCAN_PLUGIN_CLASS via init script") def pluginClass = dvOrGe(DEVELOCITY_PLUGIN_CLASS, BUILD_SCAN_PLUGIN_CLASS)
applyPluginExternally(pluginManager, BUILD_SCAN_PLUGIN_CLASS) logger.lifecycle("Applying $pluginClass via init script")
if (geUrl) { applyPluginExternally(pluginManager, pluginClass)
logger.quiet("Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer") def rootExtension = dvOrGe(
buildScan.server = geUrl { develocity },
buildScan.allowUntrustedServer = geAllowUntrustedServer { buildScan }
)
def buildScanExtension = dvOrGe(
{ rootExtension.buildScan },
{ rootExtension }
)
if (develocityUrl) {
logger.lifecycle("Connection to Develocity: $develocityUrl, allowUntrustedServer: $develocityAllowUntrustedServer, captureFileFingerprints: $develocityCaptureFileFingerprints")
rootExtension.server = develocityUrl
rootExtension.allowUntrustedServer = develocityAllowUntrustedServer
}
if (!shouldApplyDevelocityPlugin) {
// Develocity plugin publishes scans by default
buildScanExtension.publishAlways()
}
// uploadInBackground not available for build-scan-plugin 1.16
if (buildScanExtension.metaClass.respondsTo(buildScanExtension, 'setUploadInBackground', Boolean)) buildScanExtension.uploadInBackground = buildScanUploadInBackground
buildScanExtension.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, ciAutoInjectionCustomValueValue
if (isAtLeast(develocityPluginVersion, '2.1') && atLeastGradle5) {
logger.lifecycle("Setting captureFileFingerprints: $develocityCaptureFileFingerprints")
if (isAtLeast(develocityPluginVersion, '3.17')) {
buildScanExtension.capture.fileFingerprints.set(develocityCaptureFileFingerprints)
} else if (isAtLeast(develocityPluginVersion, '3.7')) {
buildScanExtension.capture.taskInputFiles = develocityCaptureFileFingerprints
} else {
buildScanExtension.captureTaskInputFiles = develocityCaptureFileFingerprints
}
} }
buildScan.publishAlways()
if (buildScan.metaClass.respondsTo(buildScan, 'setUploadInBackground', Boolean)) buildScan.uploadInBackground = buildScanUploadInBackground // uploadInBackground not available for build-scan-plugin 1.16
buildScan.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE
} }
if (geUrl && geEnforceUrl) { if (develocityUrl && develocityEnforceUrl) {
logger.lifecycle("Enforcing Develocity: $develocityUrl, allowUntrustedServer: $develocityAllowUntrustedServer, captureFileFingerprints: $develocityCaptureFileFingerprints")
}
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) { pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
afterEvaluate { afterEvaluate {
logger.quiet("Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer") if (develocityUrl && develocityEnforceUrl) {
buildScan.server = geUrl buildScan.server = develocityUrl
buildScan.allowUntrustedServer = geAllowUntrustedServer buildScan.allowUntrustedServer = develocityAllowUntrustedServer
}
} }
} }
if (buildScanTermsOfServiceUrl && buildScanTermsOfServiceAgree) { if (buildScanTermsOfUseUrl && buildScanTermsOfUseAgree) {
buildScan.termsOfServiceUrl = buildScanTermsOfServiceUrl buildScan.termsOfServiceUrl = buildScanTermsOfUseUrl
buildScan.termsOfServiceAgree = buildScanTermsOfServiceAgree buildScan.termsOfServiceAgree = buildScanTermsOfUseAgree
}
}
pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
afterEvaluate {
if (develocityUrl && develocityEnforceUrl) {
develocity.server = develocityUrl
develocity.allowUntrustedServer = develocityAllowUntrustedServer
}
}
if (buildScanTermsOfUseUrl && buildScanTermsOfUseAgree) {
develocity.buildScan.termsOfUseUrl = buildScanTermsOfUseUrl
develocity.buildScan.termsOfUseAgree = buildScanTermsOfUseAgree
}
} }
} }
@@ -137,7 +227,7 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
it.moduleVersion.with { group == "com.gradle" && name == "common-custom-user-data-gradle-plugin" } it.moduleVersion.with { group == "com.gradle" && name == "common-custom-user-data-gradle-plugin" }
} }
if (!ccudPluginComponent) { if (!ccudPluginComponent) {
logger.quiet("Applying $CCUD_PLUGIN_CLASS via init script") logger.lifecycle("Applying $CCUD_PLUGIN_CLASS via init script")
pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS)) pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS))
} }
} }
@@ -145,41 +235,73 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
} }
} else { } else {
gradle.settingsEvaluated { settings -> gradle.settingsEvaluated { settings ->
if (gePluginVersion) { if (develocityPluginVersion) {
if (!settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) { if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) && !settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
logger.quiet("Applying $DEVELOCITY_PLUGIN_CLASS via init script") def pluginClass = dvOrGe(DEVELOCITY_PLUGIN_CLASS, GRADLE_ENTERPRISE_PLUGIN_CLASS)
applyPluginExternally(settings.pluginManager, DEVELOCITY_PLUGIN_CLASS) logger.lifecycle("Applying $pluginClass via init script")
eachDevelocityExtension(settings, DEVELOCITY_EXTENSION_CLASS) { ext -> applyPluginExternally(settings.pluginManager, pluginClass)
if (geUrl) { if (develocityUrl) {
logger.quiet("Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer") logger.lifecycle("Connection to Develocity: $develocityUrl, allowUntrustedServer: $develocityAllowUntrustedServer, captureFileFingerprints: $develocityCaptureFileFingerprints")
ext.server = geUrl eachDevelocitySettingsExtension(settings, SETTINGS_EXTENSION_CLASSES) { ext ->
ext.allowUntrustedServer = geAllowUntrustedServer ext.server = develocityUrl
ext.allowUntrustedServer = develocityAllowUntrustedServer
} }
ext.buildScan.publishAlways() }
eachDevelocitySettingsExtension(settings, SETTINGS_EXTENSION_CLASSES) { ext ->
ext.buildScan.uploadInBackground = buildScanUploadInBackground ext.buildScan.uploadInBackground = buildScanUploadInBackground
ext.buildScan.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE ext.buildScan.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, ciAutoInjectionCustomValueValue
}
eachDevelocitySettingsExtension(settings, [GRADLE_ENTERPRISE_EXTENSION_CLASS]) { ext ->
ext.buildScan.publishAlways()
if (isAtLeast(develocityPluginVersion, '2.1')) {
logger.lifecycle("Setting captureFileFingerprints: $develocityCaptureFileFingerprints")
if (isAtLeast(develocityPluginVersion, '3.7')) {
ext.buildScan.capture.taskInputFiles = develocityCaptureFileFingerprints
} else {
ext.buildScan.captureTaskInputFiles = develocityCaptureFileFingerprints
}
} }
} }
if (geUrl && geEnforceUrl) { eachDevelocitySettingsExtension(settings, [DEVELOCITY_CONFIGURATION_CLASS]) { ext ->
eachDevelocityExtension(settings, DEVELOCITY_EXTENSION_CLASS) { ext -> ext.buildScan.capture.fileFingerprints = develocityCaptureFileFingerprints
logger.quiet("Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
ext.server = geUrl
ext.allowUntrustedServer = geAllowUntrustedServer
} }
} }
if (buildScanTermsOfServiceUrl && buildScanTermsOfServiceAgree) { if (develocityUrl && develocityEnforceUrl) {
eachDevelocityExtension(settings, DEVELOCITY_EXTENSION_CLASS) { ext -> logger.lifecycle("Enforcing Develocity: $develocityUrl, allowUntrustedServer: $develocityAllowUntrustedServer, captureFileFingerprints: $develocityCaptureFileFingerprints")
ext.buildScan.termsOfServiceUrl = buildScanTermsOfServiceUrl }
ext.buildScan.termsOfServiceAgree = buildScanTermsOfServiceAgree
eachDevelocitySettingsExtension(settings, [GRADLE_ENTERPRISE_EXTENSION_CLASS]) { ext ->
if (develocityUrl && develocityEnforceUrl) {
ext.server = develocityUrl
ext.allowUntrustedServer = develocityAllowUntrustedServer
}
if (buildScanTermsOfUseUrl && buildScanTermsOfUseAgree) {
ext.buildScan.termsOfServiceUrl = buildScanTermsOfUseUrl
ext.buildScan.termsOfServiceAgree = buildScanTermsOfUseAgree
}
}
eachDevelocitySettingsExtension(settings, [DEVELOCITY_CONFIGURATION_CLASS]) { ext ->
if (develocityUrl && develocityEnforceUrl) {
ext.server = develocityUrl
ext.allowUntrustedServer = develocityAllowUntrustedServer
}
if (buildScanTermsOfUseUrl && buildScanTermsOfUseAgree) {
ext.buildScan.termsOfUseUrl = buildScanTermsOfUseUrl
ext.buildScan.termsOfUseAgree = buildScanTermsOfUseAgree
} }
} }
} }
if (ccudPluginVersion) { if (ccudPluginVersion) {
if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) { if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) {
logger.quiet("Applying $CCUD_PLUGIN_CLASS via init script") logger.lifecycle("Applying $CCUD_PLUGIN_CLASS via init script")
settings.pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS)) settings.pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS))
} }
} }
@@ -188,8 +310,11 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
void applyPluginExternally(def pluginManager, String pluginClassName) { void applyPluginExternally(def pluginManager, String pluginClassName) {
def externallyApplied = 'develocity.externally-applied' def externallyApplied = 'develocity.externally-applied'
def externallyAppliedDeprecated = 'gradle.enterprise.externally-applied'
def oldValue = System.getProperty(externallyApplied) def oldValue = System.getProperty(externallyApplied)
def oldValueDeprecated = System.getProperty(externallyAppliedDeprecated)
System.setProperty(externallyApplied, 'true') System.setProperty(externallyApplied, 'true')
System.setProperty(externallyAppliedDeprecated, 'true')
try { try {
pluginManager.apply(initscript.classLoader.loadClass(pluginClassName)) pluginManager.apply(initscript.classLoader.loadClass(pluginClassName))
} finally { } finally {
@@ -198,14 +323,24 @@ void applyPluginExternally(def pluginManager, String pluginClassName) {
} else { } else {
System.setProperty(externallyApplied, oldValue) System.setProperty(externallyApplied, oldValue)
} }
if (oldValueDeprecated == null) {
System.clearProperty(externallyAppliedDeprecated)
} else {
System.setProperty(externallyAppliedDeprecated, oldValueDeprecated)
}
} }
} }
static def eachDevelocityExtension(def settings, def publicType, def action) { static def eachDevelocitySettingsExtension(def settings, List<String> publicTypes, def action) {
settings.extensions.extensionsSchema.elements.findAll { it.publicType.concreteClass.name == publicType } settings.extensions.extensionsSchema.elements.findAll { publicTypes.contains(it.publicType.concreteClass.name) }
.collect { settings[it.name] }.each(action) .collect { settings[it.name] }
.each(action)
}
static boolean isAtLeast(String versionUnderTest, String referenceVersion) {
GradleVersion.version(versionUnderTest) >= GradleVersion.version(referenceVersion)
} }
static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) { static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
GradleVersion.version(versionUnderTest) < GradleVersion.version(referenceVersion) !isAtLeast(versionUnderTest, referenceVersion)
} }

View File

@@ -20,7 +20,7 @@ dependencies {
testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') { testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') {
exclude group: 'org.codehaus.groovy', module: 'groovy-all' exclude group: 'org.codehaus.groovy', module: 'groovy-all'
} }
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.16.1' testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.17.0'
} }
test { test {

View File

@@ -1,13 +1,12 @@
plugins { plugins {
id "com.gradle.enterprise" version "3.16.2" id "com.gradle.develocity" version "3.17"
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.12.1" id "com.gradle.common-custom-user-data-gradle-plugin" version "1.13"
} }
gradleEnterprise { develocity {
buildScan { buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfServiceAgree = "yes" termsOfUseAgree = "yes"
publishAlways()
uploadInBackground = false uploadInBackground = false
} }
} }

View File

@@ -16,8 +16,8 @@ import java.nio.file.Files
import java.util.zip.GZIPOutputStream import java.util.zip.GZIPOutputStream
class BaseInitScriptTest extends Specification { class BaseInitScriptTest extends Specification {
static final String DEVELOCITY_PLUGIN_VERSION = '3.16.2' static final String DEVELOCITY_PLUGIN_VERSION = '3.17'
static final String CCUD_PLUGIN_VERSION = '1.12.1' static final String CCUD_PLUGIN_VERSION = '1.13'
static final TestGradleVersion GRADLE_3_X = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9) static final TestGradleVersion GRADLE_3_X = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9)
static final TestGradleVersion GRADLE_4_X = new TestGradleVersion(GradleVersion.version('4.10.3'), 7, 10) static final TestGradleVersion GRADLE_4_X = new TestGradleVersion(GradleVersion.version('4.10.3'), 7, 10)
@@ -129,38 +129,30 @@ class BaseInitScriptTest extends Specification {
buildFile << '' buildFile << ''
} }
def declareGePluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) { def declareDevelocityPluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) {
settingsFile.text = maybeAddPluginsToSettings(gradleVersion, null, serverUrl) + settingsFile.text settingsFile.text = maybeAddPluginsToSettings(gradleVersion, false, null, serverUrl) + settingsFile.text
buildFile.text = maybeAddPluginsToRootProject(gradleVersion, null, serverUrl) + buildFile.text buildFile.text = maybeAddPluginsToRootProject(gradleVersion, false, null, serverUrl) + buildFile.text
} }
def declareGePluginAndCcudPluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) { def declareLegacyGradleEnterprisePluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) {
settingsFile.text = maybeAddPluginsToSettings(gradleVersion, CCUD_PLUGIN_VERSION, serverUrl) + settingsFile.text settingsFile.text = maybeAddPluginsToSettings(gradleVersion, true, null, serverUrl) + settingsFile.text
buildFile.text = maybeAddPluginsToRootProject(gradleVersion, CCUD_PLUGIN_VERSION, serverUrl) + buildFile.text buildFile.text = maybeAddPluginsToRootProject(gradleVersion, true, null, serverUrl) + buildFile.text
} }
String maybeAddPluginsToSettings(GradleVersion gradleVersion, String ccudPluginVersion, URI serverUri) { def declareDevelocityPluginAndCcudPluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) {
if (gradleVersion < GradleVersion.version('5.0')) { settingsFile.text = maybeAddPluginsToSettings(gradleVersion, false, CCUD_PLUGIN_VERSION, serverUrl) + settingsFile.text
'' // applied in build.gradle buildFile.text = maybeAddPluginsToRootProject(gradleVersion, false, CCUD_PLUGIN_VERSION, serverUrl) + buildFile.text
} else if (gradleVersion < GradleVersion.version('6.0')) { }
String maybeAddPluginsToSettings(GradleVersion gradleVersion, boolean legacy, String ccudPluginVersion, URI serverUri) {
if (gradleVersion < GradleVersion.version('6.0')) {
'' // applied in build.gradle '' // applied in build.gradle
} else { } else {
""" configuredPlugin(gradleVersion, legacy, ccudPluginVersion, serverUri)
plugins {
id 'com.gradle.enterprise' version '${DEVELOCITY_PLUGIN_VERSION}'
${ccudPluginVersion ? "id 'com.gradle.common-custom-user-data-gradle-plugin' version '$ccudPluginVersion'" : ""}
}
gradleEnterprise {
server = '$serverUri'
buildScan {
publishAlways()
}
}
"""
} }
} }
String maybeAddPluginsToRootProject(GradleVersion gradleVersion, String ccudPluginVersion, URI serverUrl) { String maybeAddPluginsToRootProject(GradleVersion gradleVersion, boolean legacy, String ccudPluginVersion, URI serverUrl) {
if (gradleVersion < GradleVersion.version('5.0')) { if (gradleVersion < GradleVersion.version('5.0')) {
""" """
plugins { plugins {
@@ -173,23 +165,30 @@ class BaseInitScriptTest extends Specification {
} }
""" """
} else if (gradleVersion < GradleVersion.version('6.0')) { } else if (gradleVersion < GradleVersion.version('6.0')) {
""" configuredPlugin(gradleVersion, legacy, ccudPluginVersion, serverUrl)
plugins {
id 'com.gradle.build-scan' version '${DEVELOCITY_PLUGIN_VERSION}'
${ccudPluginVersion ? "id 'com.gradle.common-custom-user-data-gradle-plugin' version '$ccudPluginVersion'" : ""}
}
gradleEnterprise {
server = '$serverUrl'
buildScan {
publishAlways()
}
}
"""
} else { } else {
'' // applied in settings.gradle '' // applied in settings.gradle
} }
} }
String configuredPlugin(GradleVersion gradleVersion, boolean legacy, String ccudPluginVersion, URI serverUri) {
def pluginId = legacy
? (gradleVersion < GradleVersion.version('6.0') ? 'com.gradle.build-scan' : 'com.gradle.enterprise')
: 'com.gradle.develocity'
def pluginVersion = legacy ? "3.16.2" : DEVELOCITY_PLUGIN_VERSION
def configBlock = legacy ? 'gradleEnterprise' : 'develocity'
"""
plugins {
id '$pluginId' version '$pluginVersion'
${ccudPluginVersion ? "id 'com.gradle.common-custom-user-data-gradle-plugin' version '$ccudPluginVersion'" : ""}
}
$configBlock {
server = '$serverUri'
${legacy ? "buildScan { publishAlways() }" : ""}
}
"""
}
def addFailingTaskToBuild() { def addFailingTaskToBuild() {
buildFile << ''' buildFile << '''
task expectFailure { task expectFailure {

View File

@@ -58,7 +58,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
when: when:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
run(['help'], initScript, testGradleVersion.gradleVersion) run(['help'], initScript, testGradleVersion.gradleVersion)
then: then:
@@ -68,11 +68,25 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
testGradleVersion << ALL_VERSIONS testGradleVersion << ALL_VERSIONS
} }
def "produces build results file for #testGradleVersion with ge-plugin and no build scan published"() { def "produces build results file for #testGradleVersion with legacy enterprise plugin publishing build scan"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
when: when:
declareGePluginApplication(testGradleVersion.gradleVersion) declareLegacyGradleEnterprisePluginApplication(testGradleVersion.gradleVersion)
run(['help'], initScript, testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, true)
where:
testGradleVersion << ALL_VERSIONS
}
def "produces build results file for #testGradleVersion with Develocity plugin and no build scan published"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
run(['help', '--no-scan'], initScript, testGradleVersion.gradleVersion) run(['help', '--no-scan'], initScript, testGradleVersion.gradleVersion)
then: then:
@@ -86,7 +100,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
when: when:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
addFailingTaskToBuild() addFailingTaskToBuild()
runAndFail(['expectFailure'], initScript, testGradleVersion.gradleVersion) runAndFail(['expectFailure'], initScript, testGradleVersion.gradleVersion)
@@ -101,7 +115,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
when: when:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
run(['help', '--configuration-cache'], initScript, testGradleVersion.gradleVersion) run(['help', '--configuration-cache'], initScript, testGradleVersion.gradleVersion)
then: then:
@@ -122,7 +136,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
when: when:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
addFailingTaskToBuild() addFailingTaskToBuild()
failScanUpload = true failScanUpload = true
runAndFail(['expectFailure'], initScript, testGradleVersion.gradleVersion) runAndFail(['expectFailure'], initScript, testGradleVersion.gradleVersion)
@@ -165,21 +179,18 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
testGradleVersion << ALL_VERSIONS testGradleVersion << ALL_VERSIONS
} }
def "produces build results file with build scan when GE plugin is applied in settingsEvaluated"() { def "produces build results file with build scan when Develocity plugin is applied in settingsEvaluated"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
when: when:
settingsFile.text = """ settingsFile.text = """
plugins { plugins {
id 'com.gradle.enterprise' version '3.16.2' apply(false) id 'com.gradle.develocity' version '3.17' apply(false)
} }
gradle.settingsEvaluated { gradle.settingsEvaluated {
apply plugin: 'com.gradle.enterprise' apply plugin: 'com.gradle.develocity'
gradleEnterprise { develocity {
server = '$mockScansServer.address' server = '$mockScansServer.address'
buildScan {
publishAlways()
}
} }
} }
""" + settingsFile.text """ + settingsFile.text

View File

@@ -36,7 +36,7 @@ class TestDependencyGraph extends BaseInitScriptTest {
assert reportFile.exists() assert reportFile.exists()
where: where:
testGradleVersion << [GRADLE_8_X] testGradleVersion << DEPENDENCY_GRAPH_VERSIONS
} }
def "produces dependency graph with configuration-cache on latest Gradle"() { def "produces dependency graph with configuration-cache on latest Gradle"() {
@@ -127,6 +127,41 @@ class TestDependencyGraph extends BaseInitScriptTest {
testGradleVersion << DEPENDENCY_GRAPH_VERSIONS testGradleVersion << DEPENDENCY_GRAPH_VERSIONS
} }
def "can configure alternative repository for plugins"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
def vars = envVars
vars.put('GRADLE_PLUGIN_REPOSITORY_URL', 'https://plugins.grdev.net/m2')
def result = run(['help', '--info'], initScript, testGradleVersion.gradleVersion, [], vars)
then:
assert reportFile.exists()
assert result.output.contains("Resolving dependency graph plugin 1.3.0 from plugin repository: https://plugins.grdev.net/m2")
where:
testGradleVersion << DEPENDENCY_GRAPH_VERSIONS
}
def "can provide credentials for alternative repository for plugins"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
def vars = envVars
vars.put('GRADLE_PLUGIN_REPOSITORY_URL', 'https://plugins.grdev.net/m2')
vars.put('GRADLE_PLUGIN_REPOSITORY_USERNAME', 'REPO_USER')
vars.put('GRADLE_PLUGIN_REPOSITORY_PASSWORD', 'REPO_PASSWORD')
def result = run(['help', '--info'], initScript, testGradleVersion.gradleVersion, [], vars)
then:
assert reportFile.exists()
assert result.output.contains("Resolving dependency graph plugin 1.3.0 from plugin repository: https://plugins.grdev.net/m2")
assert result.output.contains("Applying credentials for plugin repository: https://plugins.grdev.net/m2")
where:
testGradleVersion << DEPENDENCY_GRAPH_VERSIONS
}
def getEnvVars() { def getEnvVars() {
return [ return [
GITHUB_DEPENDENCY_GRAPH_ENABLED: "true", GITHUB_DEPENDENCY_GRAPH_ENABLED: "true",

View File

@@ -2,6 +2,7 @@ package com.gradle.gradlebuildaction
import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import spock.lang.Requires
import static org.junit.Assume.assumeTrue import static org.junit.Assume.assumeTrue
@@ -10,7 +11,7 @@ class TestDevelocityInjection extends BaseInitScriptTest {
def initScript = 'gradle-actions.inject-develocity.init.gradle' def initScript = 'gradle-actions.inject-develocity.init.gradle'
private static final GradleVersion GRADLE_6 = GradleVersion.version('6.0') private static final GradleVersion GRADLE_5 = GradleVersion.version('5.0')
def "does not apply Develocity plugins when not requested"() { def "does not apply Develocity plugins when not requested"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
@@ -30,7 +31,31 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
given: given:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
when:
def result = run(testGradleVersion, testConfig())
then:
outputMissesDevelocityPluginApplicationViaInitScript(result)
outputMissesCcudPluginApplicationViaInitScript(result)
and:
outputContainsBuildScanUrl(result)
where:
testGradleVersion << ALL_VERSIONS
}
@Requires(
value = { data.testGradleVersion.gradleVersion >= GradleVersion.version("5.0") },
reason = "Prior to Gradle 5.0, we apply a fixed version of the plugin, which can't introduce this conflict"
)
def "does not override GE or Build Scan plugins even if Develocity plugin is requested"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
given:
declareLegacyGradleEnterprisePluginApplication(testGradleVersion.gradleVersion)
when: when:
def result = run(testGradleVersion, testConfig()) def result = run(testGradleVersion, testConfig())
@@ -63,6 +88,28 @@ class TestDevelocityInjection extends BaseInitScriptTest {
testGradleVersion << ALL_VERSIONS testGradleVersion << ALL_VERSIONS
} }
def "applies deprecated Gradle Enterprise or Build Scan plugins if requested"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
given:
def appliedPluginClass = testGradleVersion.gradleVersion >= GradleVersion.version("6.0")
? "com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin"
: "com.gradle.scan.plugin.BuildScanPlugin"
when:
// 3.16.2 is the latest version of deprecated plugins
def result = run(testGradleVersion, testConfig('3.16.2'))
then:
1 == result.output.count("Applying $appliedPluginClass via init script")
and:
outputContainsBuildScanUrl(result)
where:
testGradleVersion << ALL_VERSIONS
}
def "applies Develocity and CCUD plugins via init script when not defined in project"() { def "applies Develocity and CCUD plugins via init script when not defined in project"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
@@ -84,7 +131,7 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
given: given:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
when: when:
def result = run(testGradleVersion, testConfig().withCCUDPlugin()) def result = run(testGradleVersion, testConfig().withCCUDPlugin())
@@ -104,7 +151,7 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
given: given:
declareGePluginAndCcudPluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginAndCcudPluginApplication(testGradleVersion.gradleVersion)
when: when:
def result = run(testGradleVersion, testConfig().withCCUDPlugin()) def result = run(testGradleVersion, testConfig().withCCUDPlugin())
@@ -124,7 +171,7 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
given: given:
declareGePluginApplication(testGradleVersion.gradleVersion) declareDevelocityPluginApplication(testGradleVersion.gradleVersion)
when: when:
def config = testConfig().withServer(URI.create('https://develocity-server.invalid')) def config = testConfig().withServer(URI.create('https://develocity-server.invalid'))
@@ -165,7 +212,7 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
given: given:
declareGePluginApplication(testGradleVersion.gradleVersion, URI.create('https://develocity-server.invalid')) declareDevelocityPluginApplication(testGradleVersion.gradleVersion, URI.create('https://develocity-server.invalid'))
when: when:
def config = testConfig().withServer(mockScansServer.address, true) def config = testConfig().withServer(mockScansServer.address, true)
@@ -205,6 +252,48 @@ class TestDevelocityInjection extends BaseInitScriptTest {
testGradleVersion << ALL_VERSIONS testGradleVersion << ALL_VERSIONS
} }
def "can configure alternative repository for plugins with credentials when Develocity plugin is applied by the init script"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
def config = testConfig().withPluginRepository(new URI('https://plugins.grdev.net/m2')).withPluginRepositoryCredentials("john", "doe")
def result = run(testGradleVersion, config)
then:
outputContainsDevelocityPluginApplicationViaInitScript(result, testGradleVersion.gradleVersion)
outputContainsDevelocityConnectionInfo(result, mockScansServer.address.toString(), true)
outputMissesCcudPluginApplicationViaInitScript(result)
outputContainsPluginRepositoryInfo(result, 'https://plugins.grdev.net/m2', true)
and:
outputContainsBuildScanUrl(result)
where:
testGradleVersion << ALL_VERSIONS
}
def "can configure capturing file fingerprints when Develocity plugin is applied by the init script"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm
when:
def config = testConfig().withCaptureFileFingerprints()
def result = run(testGradleVersion, config)
then:
outputContainsDevelocityPluginApplicationViaInitScript(result, testGradleVersion.gradleVersion)
outputContainsDevelocityConnectionInfo(result, mockScansServer.address.toString(), true)
outputMissesCcudPluginApplicationViaInitScript(result)
if (testGradleVersion.gradleVersion >= GRADLE_5_X.gradleVersion) {
outputCaptureFileFingerprints(result, true)
}
and:
outputContainsBuildScanUrl(result)
where:
testGradleVersion << ALL_VERSIONS
}
def "stops gracefully when requested CCUD plugin version is <1.7"() { def "stops gracefully when requested CCUD plugin version is <1.7"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm
@@ -274,24 +363,24 @@ class TestDevelocityInjection extends BaseInitScriptTest {
} }
void outputContainsDevelocityPluginApplicationViaInitScript(BuildResult result, GradleVersion gradleVersion) { void outputContainsDevelocityPluginApplicationViaInitScript(BuildResult result, GradleVersion gradleVersion) {
def pluginApplicationLogMsgGradle4And5 = "Applying com.gradle.scan.plugin.BuildScanPlugin via init script" def pluginApplicationLogMsgGradle4 = "Applying com.gradle.scan.plugin.BuildScanPlugin via init script"
def pluginApplicationLogMsgGradle6AndHigher = "Applying com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin via init script" def pluginApplicationLogMsgGradle5AndHigher = "Applying com.gradle.develocity.agent.gradle.DevelocityPlugin via init script"
if (gradleVersion < GRADLE_6) { if (gradleVersion < GRADLE_5) {
assert result.output.contains(pluginApplicationLogMsgGradle4And5) assert result.output.contains(pluginApplicationLogMsgGradle4)
assert 1 == result.output.count(pluginApplicationLogMsgGradle4And5) assert 1 == result.output.count(pluginApplicationLogMsgGradle4)
assert !result.output.contains(pluginApplicationLogMsgGradle6AndHigher) assert !result.output.contains(pluginApplicationLogMsgGradle5AndHigher)
} else { } else {
assert result.output.contains(pluginApplicationLogMsgGradle6AndHigher) assert result.output.contains(pluginApplicationLogMsgGradle5AndHigher)
assert 1 == result.output.count(pluginApplicationLogMsgGradle6AndHigher) assert 1 == result.output.count(pluginApplicationLogMsgGradle5AndHigher)
assert !result.output.contains(pluginApplicationLogMsgGradle4And5) assert !result.output.contains(pluginApplicationLogMsgGradle4)
} }
} }
void outputMissesDevelocityPluginApplicationViaInitScript(BuildResult result) { void outputMissesDevelocityPluginApplicationViaInitScript(BuildResult result) {
def pluginApplicationLogMsgGradle4And5 = "Applying com.gradle.scan.plugin.BuildScanPlugin via init script" def pluginApplicationLogMsgGradle4 = "Applying com.gradle.scan.plugin.BuildScanPlugin via init script"
def pluginApplicationLogMsgGradle6AndHigher = "Applying com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin via init script" def pluginApplicationLogMsgGradle5AndHigher = "Applying com.gradle.develocity.agent.gradle.DevelocityPlugin via init script"
assert !result.output.contains(pluginApplicationLogMsgGradle4And5) assert !result.output.contains(pluginApplicationLogMsgGradle4)
assert !result.output.contains(pluginApplicationLogMsgGradle6AndHigher) assert !result.output.contains(pluginApplicationLogMsgGradle5AndHigher)
} }
void outputContainsCcudPluginApplicationViaInitScript(BuildResult result) { void outputContainsCcudPluginApplicationViaInitScript(BuildResult result) {
@@ -305,20 +394,32 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assert !result.output.contains(pluginApplicationLogMsg) assert !result.output.contains(pluginApplicationLogMsg)
} }
void outputContainsDevelocityConnectionInfo(BuildResult result, String geUrl, boolean geAllowUntrustedServer) { void outputContainsDevelocityConnectionInfo(BuildResult result, String develocityUrl, boolean develocityAllowUntrustedServer) {
def geConnectionInfo = "Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer" def develocityConnectionInfo = "Connection to Develocity: $develocityUrl, allowUntrustedServer: $develocityAllowUntrustedServer"
assert result.output.contains(geConnectionInfo) assert result.output.contains(develocityConnectionInfo)
assert 1 == result.output.count(geConnectionInfo) assert 1 == result.output.count(develocityConnectionInfo)
} }
void outputContainsPluginRepositoryInfo(BuildResult result, String gradlePluginRepositoryUrl) { void outputCaptureFileFingerprints(BuildResult result, boolean captureFileFingerprints) {
def captureFileFingerprintsInfo = "Setting captureFileFingerprints: $captureFileFingerprints"
assert result.output.contains(captureFileFingerprintsInfo)
assert 1 == result.output.count(captureFileFingerprintsInfo)
}
void outputContainsPluginRepositoryInfo(BuildResult result, String gradlePluginRepositoryUrl, boolean withCredentials = false) {
def repositoryInfo = "Develocity plugins resolution: ${gradlePluginRepositoryUrl}" def repositoryInfo = "Develocity plugins resolution: ${gradlePluginRepositoryUrl}"
assert result.output.contains(repositoryInfo) assert result.output.contains(repositoryInfo)
assert 1 == result.output.count(repositoryInfo) assert 1 == result.output.count(repositoryInfo)
if (withCredentials) {
def credentialsInfo = "Using credentials for plugin repository"
assert result.output.contains(credentialsInfo)
assert 1 == result.output.count(credentialsInfo)
}
} }
void outputEnforcesDevelocityUrl(BuildResult result, String geUrl, boolean geAllowUntrustedServer) { void outputEnforcesDevelocityUrl(BuildResult result, String develocityUrl, boolean develocityAllowUntrustedServer) {
def enforceUrl = "Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer" def enforceUrl = "Enforcing Develocity: $develocityUrl, allowUntrustedServer: $develocityAllowUntrustedServer"
assert result.output.contains(enforceUrl) assert result.output.contains(enforceUrl)
assert 1 == result.output.count(enforceUrl) assert 1 == result.output.count(enforceUrl)
} }
@@ -341,8 +442,8 @@ class TestDevelocityInjection extends BaseInitScriptTest {
} }
} }
private TestConfig testConfig() { private TestConfig testConfig(String develocityPluginVersion = DEVELOCITY_PLUGIN_VERSION) {
new TestConfig() new TestConfig(develocityPluginVersion)
} }
class TestConfig { class TestConfig {
@@ -350,6 +451,14 @@ class TestDevelocityInjection extends BaseInitScriptTest {
boolean enforceUrl = false boolean enforceUrl = false
String ccudPluginVersion = null String ccudPluginVersion = null
String pluginRepositoryUrl = null String pluginRepositoryUrl = null
String pluginRepositoryUsername = null
String pluginRepositoryPassword = null
boolean captureFileFingerprints = false
String develocityPluginVersion
TestConfig(String develocityPluginVersion) {
this.develocityPluginVersion = develocityPluginVersion
}
TestConfig withCCUDPlugin(String version = CCUD_PLUGIN_VERSION) { TestConfig withCCUDPlugin(String version = CCUD_PLUGIN_VERSION) {
ccudPluginVersion = version ccudPluginVersion = version
@@ -367,33 +476,54 @@ class TestDevelocityInjection extends BaseInitScriptTest {
return this return this
} }
TestConfig withCaptureFileFingerprints() {
this.captureFileFingerprints = true
return this
}
TestConfig withPluginRepositoryCredentials(String pluginRepoUsername, String pluginRepoPassword) {
this.pluginRepositoryUsername = pluginRepoUsername
this.pluginRepositoryPassword = pluginRepoPassword
return this
}
def getEnvVars() { def getEnvVars() {
Map<String, String> envVars = [ Map<String, String> envVars = [
DEVELOCITY_INJECTION_ENABLED: "true", DEVELOCITY_INJECTION_INIT_SCRIPT_NAME : "gradle-actions.inject-develocity.init.gradle",
DEVELOCITY_URL: serverUrl, DEVELOCITY_INJECTION_ENABLED : "true",
DEVELOCITY_ALLOW_UNTRUSTED_SERVER: "true", DEVELOCITY_URL : serverUrl,
DEVELOCITY_PLUGIN_VERSION: DEVELOCITY_PLUGIN_VERSION, DEVELOCITY_ALLOW_UNTRUSTED_SERVER : "true",
DEVELOCITY_BUILD_SCAN_UPLOAD_IN_BACKGROUND: "true" // Need to upload in background since our Mock server doesn't cope with foreground upload DEVELOCITY_PLUGIN_VERSION : develocityPluginVersion,
DEVELOCITY_BUILD_SCAN_UPLOAD_IN_BACKGROUND: "true", // Need to upload in background since our Mock server doesn't cope with foreground upload
DEVELOCITY_AUTO_INJECTION_CUSTOM_VALUE : 'gradle-actions'
] ]
if (enforceUrl) envVars.put("DEVELOCITY_ENFORCE_URL", "true") if (enforceUrl) envVars.put("DEVELOCITY_ENFORCE_URL", "true")
if (ccudPluginVersion != null) envVars.put("DEVELOCITY_CCUD_PLUGIN_VERSION", ccudPluginVersion) if (ccudPluginVersion != null) envVars.put("DEVELOCITY_CCUD_PLUGIN_VERSION", ccudPluginVersion)
if (pluginRepositoryUrl != null) envVars.put("GRADLE_PLUGIN_REPOSITORY_URL", pluginRepositoryUrl) if (pluginRepositoryUrl != null) envVars.put("GRADLE_PLUGIN_REPOSITORY_URL", pluginRepositoryUrl)
if (pluginRepositoryUsername != null) envVars.put("GRADLE_PLUGIN_REPOSITORY_USERNAME", pluginRepositoryUsername)
if (pluginRepositoryPassword != null) envVars.put("GRADLE_PLUGIN_REPOSITORY_PASSWORD", pluginRepositoryPassword)
if (captureFileFingerprints) envVars.put("DEVELOCITY_CAPTURE_FILE_FINGERPRINTS", "true")
return envVars return envVars
} }
def getJvmArgs() { def getJvmArgs() {
List<String> jvmArgs = [ List<String> jvmArgs = [
"-Ddevelocity.injection.init-script-name=gradle-actions.inject-develocity.init.gradle",
"-Ddevelocity.injection-enabled=true", "-Ddevelocity.injection-enabled=true",
"-Ddevelocity.url=$serverUrl", "-Ddevelocity.url=$serverUrl",
"-Ddevelocity.allow-untrusted-server=true", "-Ddevelocity.allow-untrusted-server=true",
"-Ddevelocity.plugin.version=$DEVELOCITY_PLUGIN_VERSION", "-Ddevelocity.plugin.version=$develocityPluginVersion",
"-Ddevelocity.build-scan.upload-in-background=true" "-Ddevelocity.build-scan.upload-in-background=true",
"-Ddevelocity.auto-injection.custom-value=gradle-actions"
] ]
if (enforceUrl) jvmArgs.add("-Ddevelocity.enforce-url=true") if (enforceUrl) jvmArgs.add("-Ddevelocity.enforce-url=true")
if (ccudPluginVersion != null) jvmArgs.add("-Ddevelocity.ccud-plugin.version=$ccudPluginVersion") if (ccudPluginVersion != null) jvmArgs.add("-Ddevelocity.ccud-plugin.version=$ccudPluginVersion")
if (pluginRepositoryUrl != null) jvmArgs.add("-Dgradle.plugin-repository.url=$pluginRepositoryUrl") if (pluginRepositoryUrl != null) jvmArgs.add("-Dgradle.plugin-repository.url=$pluginRepositoryUrl")
if (pluginRepositoryUsername != null) jvmArgs.add("-Dgradle.plugin-repository.username=$pluginRepositoryUsername")
if (pluginRepositoryPassword != null) jvmArgs.add("-Dgradle.plugin-repository.password=$pluginRepositoryPassword")
if (captureFileFingerprints) jvmArgs.add("-Ddevelocity.capture-file-fingerprints=true")
return jvmArgs.collect { it.toString() } // Convert from GStrings return jvmArgs.collect { it.toString() } // Convert from GStrings
} }

1
sources/test/jest/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
tmp

View File

@@ -23,13 +23,13 @@ test('will cleanup unused dependency jars and build-cache entries', async () =>
expect(fs.existsSync(commonsMath31)).toBe(true) expect(fs.existsSync(commonsMath31)).toBe(true)
expect(fs.existsSync(commonsMath311)).toBe(true) expect(fs.existsSync(commonsMath311)).toBe(true)
expect(fs.readdirSync(buildCacheDir).length).toBe(4) expect(fs.readdirSync(buildCacheDir).length).toBe(6)
await cacheCleaner.forceCleanup() await cacheCleaner.forceCleanup()
expect(fs.existsSync(commonsMath31)).toBe(false) expect(fs.existsSync(commonsMath31)).toBe(false)
expect(fs.existsSync(commonsMath311)).toBe(true) expect(fs.existsSync(commonsMath311)).toBe(true)
expect(fs.readdirSync(buildCacheDir).length).toBe(3) expect(fs.readdirSync(buildCacheDir).length).toBe(5)
}) })
test('will cleanup unused gradle versions', async () => { test('will cleanup unused gradle versions', async () => {
@@ -49,7 +49,7 @@ test('will cleanup unused gradle versions', async () => {
const gradle802 = path.resolve(gradleUserHome, "caches/8.0.2") const gradle802 = path.resolve(gradleUserHome, "caches/8.0.2")
const wrapper802 = path.resolve(gradleUserHome, "wrapper/dists/gradle-8.0.2-bin") const wrapper802 = path.resolve(gradleUserHome, "wrapper/dists/gradle-8.0.2-bin")
const gradleCurrent = path.resolve(gradleUserHome, "caches/8.5") const gradleCurrent = path.resolve(gradleUserHome, "caches/8.7")
expect(fs.existsSync(gradle802)).toBe(true) expect(fs.existsSync(gradle802)).toBe(true)
expect(fs.existsSync(wrapper802)).toBe(true) expect(fs.existsSync(wrapper802)).toBe(true)

View File

@@ -0,0 +1,34 @@
import {GradleStateCache} from "../../src/cache-base"
import * as path from 'path'
import * as fs from 'fs'
const testTmp = 'test/jest/tmp'
fs.rmSync(testTmp, {recursive: true, force: true})
describe("--info and --stacktrace", () => {
describe("will be created", () => {
it("when gradle.properties does not exists", async () => {
const emptyGradleHome = `${testTmp}/empty-gradle-home`
fs.mkdirSync(emptyGradleHome, {recursive: true})
const stateCache = new GradleStateCache("ignored", emptyGradleHome)
stateCache.configureInfoLogLevel()
expect(fs.readFileSync(path.resolve(emptyGradleHome, "gradle.properties"), 'utf-8'))
.toBe("org.gradle.logging.level=info\norg.gradle.logging.stacktrace=all\n")
})
})
describe("will be added", () => {
it("and gradle.properties does exists", async () => {
const existingGradleHome = `${testTmp}/existing-gradle-home`
fs.mkdirSync(existingGradleHome, {recursive: true})
fs.writeFileSync(path.resolve(existingGradleHome, "gradle.properties"), "org.gradle.logging.level=debug\n")
const stateCache = new GradleStateCache("ignored", existingGradleHome)
stateCache.configureInfoLogLevel()
expect(fs.readFileSync(path.resolve(existingGradleHome, "gradle.properties"), 'utf-8'))
.toBe("org.gradle.logging.level=info\norg.gradle.logging.stacktrace=all\n\norg.gradle.logging.level=debug\n")
})
})
})