mirror of
https://github.com/gradle/gradle-build-action.git
synced 2025-10-20 07:08:56 +08:00
Compare commits
410 Commits
v2.2.3
...
v3-prerele
Author | SHA1 | Date | |
---|---|---|---|
|
6c7537229b | ||
|
650620f9f9 | ||
|
d4e24dfc10 | ||
|
7c57ba1136 | ||
|
32bab5b15a | ||
|
270f30ba56 | ||
|
c00a847f3f | ||
|
e2aa3f332c | ||
|
ff5d63e9dc | ||
|
4faac45dc8 | ||
|
45ed60450e | ||
|
72abd931ce | ||
|
a4107da76d | ||
|
d16a3f4093 | ||
|
333078158e | ||
|
34a07dced0 | ||
|
24e9e9dc6b | ||
|
bc72ac9e9d | ||
|
c791d32284 | ||
|
ceb0c736c1 | ||
|
3f2ca32cb0 | ||
|
5d2dd0dea4 | ||
|
e865911745 | ||
|
0538e78c32 | ||
|
a4dabb3a70 | ||
|
51b7a82e8e | ||
|
92cb3fe7e8 | ||
|
e843ea4565 | ||
|
14b4921945 | ||
|
9c7269b85b | ||
|
a7b743845f | ||
|
e6566cde89 | ||
|
89f8dcd819 | ||
|
93050d1483 | ||
|
df38ec05e0 | ||
|
b3f092e821 | ||
|
63ce84df08 | ||
|
57f3f23714 | ||
|
38785d7d62 | ||
|
a738af78ea | ||
|
ae24bf6608 | ||
|
334a4b8d4d | ||
|
009bd36b91 | ||
|
9d6738618d | ||
|
f053e6b7e7 | ||
|
c821b7c4f1 | ||
|
982da8e78c | ||
|
a0fc8606d2 | ||
|
a1980784de | ||
|
89e46180c6 | ||
|
f95e9c7459 | ||
|
8cbcb9948b | ||
|
a71aff6a12 | ||
|
77699bae74 | ||
|
dc5927259f | ||
|
4f0075d967 | ||
|
e1f9864a52 | ||
|
76d5a9b475 | ||
|
39d8c6d06e | ||
|
0280eb7de5 | ||
|
87a9a15658 | ||
|
375481748b | ||
|
beff1c573c | ||
|
21a3ebb55f | ||
|
a5be560235 | ||
|
9bca466e27 | ||
|
f757bcfd86 | ||
|
8b6c211905 | ||
|
8db1c7621b | ||
|
6eaacfc06c | ||
|
750905c0ed | ||
|
d5fbcc8361 | ||
|
0e761ca2b4 | ||
|
6b7c087721 | ||
|
0bfe00a136 | ||
|
62cce3c597 | ||
|
842c587ad8 | ||
|
4241e05054 | ||
|
bfa3c0508e | ||
|
c3bdce8205 | ||
|
f92e7c3428 | ||
|
d1b726d8c1 | ||
|
6fcc109efa | ||
|
fde5b4fcde | ||
|
324fbdc804 | ||
|
5658338fb0 | ||
|
87ccc98a2a | ||
|
4441c9f9bf | ||
|
b5126f31db | ||
|
d8615ccc8b | ||
|
444c20baf7 | ||
|
aea76e1766 | ||
|
103e3a7ba7 | ||
|
73e3fc21c7 | ||
|
b063df05a4 | ||
|
5e3952da92 | ||
|
ed940a329a | ||
|
3bfe3a4658 | ||
|
8f08e41675 | ||
|
ef76a971e2 | ||
|
98d77952ea | ||
|
3122f2c659 | ||
|
53c4cf6c4c | ||
|
f2d7085b02 | ||
|
9124f04a83 | ||
|
c304f927c4 | ||
|
e3426b1f20 | ||
|
d79398df06 | ||
|
b9cd1d9e69 | ||
|
d4db33d499 | ||
|
05acc776e8 | ||
|
33c9bfac14 | ||
|
97d9c134b7 | ||
|
a617adb316 | ||
|
b156d58cac | ||
|
b946c060aa | ||
|
96bed685e4 | ||
|
800e5e1e62 | ||
|
ff3f4cfbf8 | ||
|
a07019c726 | ||
|
b17d107b8c | ||
|
12dcfaa735 | ||
|
9fb6114fb4 | ||
|
50d07aa0e5 | ||
|
3d49588efc | ||
|
68e1dcdea4 | ||
|
8cade330d4 | ||
|
124cb765ee | ||
|
243af859f8 | ||
|
dc5f59ec6e | ||
|
c87c55823d | ||
|
cfdcfc37ed | ||
|
193108951e | ||
|
f9b4995b32 | ||
|
4283247a19 | ||
|
337198a5e3 | ||
|
e3028deccc | ||
|
cb1fda6460 | ||
|
19e2bdf3c0 | ||
|
891451e1fc | ||
|
03f0ac2c51 | ||
|
999ba18af8 | ||
|
43f8f93391 | ||
|
e8d1617724 | ||
|
a4cf152f48 | ||
|
a8aac055e2 | ||
|
7241fa5d56 | ||
|
9e58f8b1de | ||
|
632e888003 | ||
|
ced6859e9c | ||
|
0904709a46 | ||
|
1b94073332 | ||
|
4821f54162 | ||
|
2dbad1ea2d | ||
|
915a66c096 | ||
|
8e5c8782a3 | ||
|
9f977db2d8 | ||
|
fa27d06744 | ||
|
a0fdbb009a | ||
|
f59a6d4310 | ||
|
b69de5f2a9 | ||
|
3c11eee5f9 | ||
|
4301451b53 | ||
|
295170c2ce | ||
|
ce999babab | ||
|
ce35ffa374 | ||
|
ad97b0f09e | ||
|
29c79cfd95 | ||
|
bd57605957 | ||
|
f464d5c9e5 | ||
|
cef72ff9e4 | ||
|
7a67f395d2 | ||
|
bc190ca89a | ||
|
f01b48d89d | ||
|
1e71bceb3f | ||
|
9a4d99b236 | ||
|
33f9bc031c | ||
|
437bff62b6 | ||
|
c0186c5832 | ||
|
ee7ca6ac9b | ||
|
063cc1c708 | ||
|
820b228f28 | ||
|
d0ffeaa089 | ||
|
4c9c435d2f | ||
|
a6ad1901be | ||
|
d7761f188f | ||
|
92c37aaab7 | ||
|
1a6aca96f3 | ||
|
90c9cfa90d | ||
|
35af09efd8 | ||
|
00309f16a9 | ||
|
3273b6ada1 | ||
|
f807993b34 | ||
|
bde650d6f1 | ||
|
40b6781dcd | ||
|
626d937994 | ||
|
6c3f1eadfe | ||
|
8e02c8272a | ||
|
f63cb02cfc | ||
|
198484d871 | ||
|
fce96e0d6a | ||
|
75a86cfe02 | ||
|
be413309fa | ||
|
1b2daf5833 | ||
|
4388b1f9e5 | ||
|
07023d3e3e | ||
|
c94d573317 | ||
|
680037c65b | ||
|
2bf6bc3646 | ||
|
631021bf98 | ||
|
d1c4012c0d | ||
|
c097126a28 | ||
|
b4a540a61f | ||
|
c9a87440e3 | ||
|
d23c38fad3 | ||
|
a810b86311 | ||
|
7e48093f71 | ||
|
12681a2972 | ||
|
a8aa75965b | ||
|
a580d9bd57 | ||
|
a13870c94e | ||
|
55d241b8a2 | ||
|
9cf99034d2 | ||
|
6778644d75 | ||
|
749f47bda3 | ||
|
eb126d771e | ||
|
5056fa9d50 | ||
|
8a0051ffb2 | ||
|
4f87177da0 | ||
|
ff62946998 | ||
|
2eddd207d6 | ||
|
887e0bda35 | ||
|
dac0b87334 | ||
|
a8f0f0d523 | ||
|
951bc8ab16 | ||
|
c0e9e4809f | ||
|
c5df77b4dd | ||
|
f04973c111 | ||
|
2287707267 | ||
|
530c579a03 | ||
|
f65e80839b | ||
|
fed795f38c | ||
|
a63ae37710 | ||
|
6095a76664 | ||
|
96015f1e52 | ||
|
4a570433d8 | ||
|
601a5d4aa4 | ||
|
6df3b5baf5 | ||
|
96374ed57d | ||
|
59d37bdb61 | ||
|
5abf330283 | ||
|
86ee4f1f60 | ||
|
e0391a3985 | ||
|
09af07ef76 | ||
|
b47aad4750 | ||
|
758ee5a303 | ||
|
50f436c485 | ||
|
32863c1a40 | ||
|
b744d1079a | ||
|
bff802913e | ||
|
cacfec068e | ||
|
935e8941dd | ||
|
cfc50b189a | ||
|
7e68f96bb3 | ||
|
e444647395 | ||
|
970a1475f1 | ||
|
d9106fb21d | ||
|
6f59210bbe | ||
|
a8cfaf666b | ||
|
c82ad7fca4 | ||
|
e70e4c5e6b | ||
|
2bc6cca4b8 | ||
|
38bf8d67e6 | ||
|
1c56ebc005 | ||
|
7b3886699e | ||
|
c7ca785b85 | ||
|
dbca794d9a | ||
|
cbd0ff0688 | ||
|
1e6c29c1af | ||
|
d518883ba8 | ||
|
b3d342ca6a | ||
|
f7e0e454da | ||
|
60499ea6fd | ||
|
e4ca0fdab0 | ||
|
9adc0d5566 | ||
|
b1d3b7d6a0 | ||
|
43879ebea6 | ||
|
a64e4c087d | ||
|
3952b17b6f | ||
|
cb48b1f38e | ||
|
68ef9a8880 | ||
|
980f056e16 | ||
|
57f5c44cc6 | ||
|
e34d59c741 | ||
|
3d966761cf | ||
|
1b220aef6b | ||
|
a40cc892c0 | ||
|
7a088f07a3 | ||
|
ce77f6daf4 | ||
|
ba25077191 | ||
|
ea2e601207 | ||
|
4ebaed58ba | ||
|
9884d8f3dc | ||
|
2e30e4cc65 | ||
|
2fcb85ffb5 | ||
|
617a29d5b5 | ||
|
0ea8b0085d | ||
|
084bf86b45 | ||
|
a1c0141aa8 | ||
|
19307c73ca | ||
|
12054785f0 | ||
|
5d67aff3ea | ||
|
c2abdfc02b | ||
|
4d24cb28d8 | ||
|
9db683d515 | ||
|
45abe419bb | ||
|
d9799478b8 | ||
|
579b14502b | ||
|
a0cffe83e1 | ||
|
add2af0efd | ||
|
1fcc75d614 | ||
|
5df685c7b2 | ||
|
ee7cbb6fb4 | ||
|
1d2e9eb287 | ||
|
2df8f7bc66 | ||
|
3fbe033aaa | ||
|
0842a550d1 | ||
|
3b959539de | ||
|
c267ad1fcb | ||
|
fab7664a6a | ||
|
a5b34e05de | ||
|
a4b5212a9d | ||
|
ad59e53998 | ||
|
c224a16628 | ||
|
ec783957f3 | ||
|
6b08b7d2b5 | ||
|
fd32ae9081 | ||
|
8545e5aed7 | ||
|
d92395703c | ||
|
af916fa394 | ||
|
3d9f1fdd28 | ||
|
387c8bc97a | ||
|
31c4390f56 | ||
|
05b706c1e7 | ||
|
b9a8697f71 | ||
|
394498f89f | ||
|
c295a4096e | ||
|
74a56b60ce | ||
|
aeb3e0fcd7 | ||
|
8a17724c3e | ||
|
76ed799d26 | ||
|
dd8493d4f2 | ||
|
66061a0409 | ||
|
1a66a38284 | ||
|
bf471096d3 | ||
|
e8a7e1402f | ||
|
0e3ce37aac | ||
|
8d2472536e | ||
|
832889a6eb | ||
|
61f7cb1f75 | ||
|
e440eaf750 | ||
|
570f67893a | ||
|
402732a560 | ||
|
a6f860c57c | ||
|
657d21ac23 | ||
|
688380a438 | ||
|
cce16c4e36 | ||
|
b50380a07d | ||
|
aa2854e6ea | ||
|
471bcda20a | ||
|
91306f47ea | ||
|
65c865a172 | ||
|
1761dcff13 | ||
|
356abb47e7 | ||
|
fc9e8feb61 | ||
|
0e4b100458 | ||
|
82bc72e1e7 | ||
|
8be955ee80 | ||
|
531cc21aeb | ||
|
164712adb1 | ||
|
535b494721 | ||
|
d6110ecac2 | ||
|
cc60593845 | ||
|
fb549a8417 | ||
|
c64fe31590 | ||
|
6e56b59601 | ||
|
c77676cc69 | ||
|
f39ea084f9 | ||
|
27a2f232f6 | ||
|
b4c3d51488 | ||
|
99ec710825 | ||
|
d427a379a8 | ||
|
ed5f3e6998 | ||
|
11c5fa73ac | ||
|
3e3c80e9b4 | ||
|
25ec178747 | ||
|
3cc0a8f6bb | ||
|
915123c493 | ||
|
ef638c00fd | ||
|
05257c7a5f | ||
|
c1a6f51e61 | ||
|
865815e1b6 | ||
|
eb22e65b5b | ||
|
8a386f6915 | ||
|
84bc83e639 | ||
|
cd579d970f | ||
|
f0ec7fb780 | ||
|
bf2a15ee94 | ||
|
c85b5e1be7 | ||
|
330980897f |
@@ -12,6 +12,7 @@
|
||||
"import/no-namespace": "off",
|
||||
"i18n-text/no-en": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-shadow": "off",
|
||||
"sort-imports": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
||||
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
|
||||
@@ -29,7 +30,8 @@
|
||||
"@typescript-eslint/no-inferrable-types": "error",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-shadow": "error",
|
||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||
"@typescript-eslint/no-useless-constructor": "error",
|
||||
|
2
.github/actions/build-dist/action.yml
vendored
2
.github/actions/build-dist/action.yml
vendored
@@ -7,7 +7,7 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
npm install
|
||||
npm run all
|
||||
npm run build
|
||||
- name: Upload distribution
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
24
.github/dependabot.yml
vendored
24
.github/dependabot.yml
vendored
@@ -6,13 +6,27 @@ registries:
|
||||
username: dummy # Required by dependabot
|
||||
password: dummy # Required by dependabot
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: "@types/node"
|
||||
- dependency-name: "@types/node" # Breaking change: update with next major release
|
||||
- dependency-name: "@octokit/rest" # Tied to node version
|
||||
groups:
|
||||
npm-dependencies:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "gradle"
|
||||
directory: ".github/workflow-samples/gradle-plugin"
|
||||
registries:
|
||||
@@ -49,3 +63,9 @@ updates:
|
||||
- gradle-plugin-portal
|
||||
schedule:
|
||||
interval: "daily"
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "test/init-scripts"
|
||||
registries:
|
||||
- gradle-plugin-portal
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
35
.github/workflow-samples/gradle-plugin/gradlew
vendored
35
.github/workflow-samples/gradle-plugin/gradlew
vendored
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# 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/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# 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
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
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
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# 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" \
|
||||
|
@@ -26,6 +26,7 @@ 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%
|
||||
|
||||
|
@@ -29,7 +29,7 @@ testing {
|
||||
functionalTest(JvmTestSuite) {
|
||||
dependencies {
|
||||
// functionalTest test suite depends on the production code in tests
|
||||
implementation project
|
||||
implementation(project(':plugin'))
|
||||
}
|
||||
|
||||
targets {
|
||||
|
@@ -11,8 +11,8 @@ dependencies {
|
||||
}
|
||||
|
||||
tasks.named("test").configure {
|
||||
// Echo an output value so we can detect configuration-cache usage
|
||||
println "::set-output name=task_configured::yes"
|
||||
// Write marker file so we can detect if task was configured
|
||||
file("task-configured.txt").text = "true"
|
||||
|
||||
doLast {
|
||||
if (System.properties.verifyCachedBuild) {
|
||||
|
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
35
.github/workflow-samples/groovy-dsl/gradlew
vendored
35
.github/workflow-samples/groovy-dsl/gradlew
vendored
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# 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/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# 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
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
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
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# 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" \
|
||||
|
@@ -26,6 +26,7 @@ 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%
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.11.1"
|
||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.8.0"
|
||||
id "com.gradle.enterprise" version "3.16.1"
|
||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.12.1"
|
||||
}
|
||||
|
||||
gradleEnterprise {
|
||||
|
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
35
.github/workflow-samples/java-toolchain/gradlew
vendored
35
.github/workflow-samples/java-toolchain/gradlew
vendored
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# 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/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# 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
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
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
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# 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" \
|
||||
|
@@ -26,6 +26,7 @@ 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%
|
||||
|
||||
|
@@ -1 +1,5 @@
|
||||
plugins {
|
||||
id("org.gradle.toolchains.foojay-resolver-convention") version("0.7.0")
|
||||
}
|
||||
|
||||
rootProject.name = 'basic'
|
||||
|
@@ -8,9 +8,9 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
api("org.apache.commons:commons-math3:3.6.1")
|
||||
implementation("com.google.guava:guava:31.1-jre")
|
||||
implementation("com.google.guava:guava:33.0.0-jre")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.0")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
@@ -18,8 +18,8 @@ tasks.test {
|
||||
}
|
||||
|
||||
tasks.named("test").configure {
|
||||
// Echo an output value so we can detect configuration-cache usage
|
||||
println("::set-output name=task_configured::yes")
|
||||
// Write marker file so we can detect if task was configured
|
||||
file("task-configured.txt").writeText("true")
|
||||
|
||||
doLast {
|
||||
if (System.getProperties().containsKey("verifyCachedBuild")) {
|
||||
|
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
35
.github/workflow-samples/kotlin-dsl/gradlew
vendored
35
.github/workflow-samples/kotlin-dsl/gradlew
vendored
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# 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/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# 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
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
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
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# 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" \
|
||||
|
@@ -26,6 +26,7 @@ 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%
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("com.gradle.enterprise") version "3.11.1"
|
||||
id("com.gradle.common-custom-user-data-gradle-plugin") version "1.8.0"
|
||||
id("com.gradle.enterprise") version "3.16.1"
|
||||
id("com.gradle.common-custom-user-data-gradle-plugin") version "1.12.1"
|
||||
}
|
||||
|
||||
gradleEnterprise {
|
||||
|
1
.github/workflow-samples/no-ge/build.gradle
vendored
Normal file
1
.github/workflow-samples/no-ge/build.gradle
vendored
Normal file
@@ -0,0 +1 @@
|
||||
// Required to keep dependabot happy
|
1
.github/workflow-samples/no-ge/settings.gradle
vendored
Normal file
1
.github/workflow-samples/no-ge/settings.gradle
vendored
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'no-ge'
|
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.build-scan" version "3.11.1"
|
||||
id "com.gradle.build-scan" version "3.16.1"
|
||||
}
|
||||
|
||||
gradleEnterprise {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.11.1"
|
||||
id "com.gradle.enterprise" version "3.16.1"
|
||||
}
|
||||
|
||||
gradleEnterprise {
|
||||
|
8
.github/workflows/ci-codeql.yml
vendored
8
.github/workflows/ci-codeql.yml
vendored
@@ -38,11 +38,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -67,4 +67,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
20
.github/workflows/ci-dependency-review.yml
vendored
Normal file
20
.github/workflows/ci-dependency-review.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Dependency Review Action
|
||||
#
|
||||
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
|
||||
#
|
||||
# Source repository: https://github.com/actions/dependency-review-action
|
||||
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
|
||||
name: CI-dependency-review
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v4
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v3
|
31
.github/workflows/ci-full-check.yml
vendored
31
.github/workflows/ci-full-check.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: CI-full-check
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types:
|
||||
- assigned
|
||||
@@ -9,7 +10,7 @@ on:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- '.github/**'
|
||||
- 'dist/**'
|
||||
|
||||
jobs:
|
||||
@@ -18,8 +19,20 @@ jobs:
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
||||
cache-cleanup:
|
||||
uses: ./.github/workflows/integ-test-cache-cleanup.yml
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
||||
caching-config:
|
||||
uses: ./.github/workflows/integ-test-action-inputs-caching.yml
|
||||
uses: ./.github/workflows/integ-test-caching-config.yml
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
||||
dependency-graph:
|
||||
uses: ./.github/workflows/integ-test-dependency-graph.yml
|
||||
permissions:
|
||||
contents: write
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
||||
@@ -33,6 +46,13 @@ jobs:
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
||||
gradle-enterprise-injection:
|
||||
uses: ./.github/workflows/integ-test-inject-gradle-enterprise.yml
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
secrets:
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
|
||||
|
||||
provision-gradle-versions:
|
||||
uses: ./.github/workflows/integ-test-provision-gradle-versions.yml
|
||||
with:
|
||||
@@ -42,6 +62,8 @@ jobs:
|
||||
uses: ./.github/workflows/integ-test-restore-configuration-cache.yml
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
secrets:
|
||||
GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
|
||||
restore-custom-gradle-home:
|
||||
uses: ./.github/workflows/integ-test-restore-custom-gradle-home.yml
|
||||
@@ -72,3 +94,8 @@ jobs:
|
||||
uses: ./.github/workflows/integ-test-sample-gradle-plugin.yml
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
||||
toolchain-detection:
|
||||
uses: ./.github/workflows/integ-test-detect-java-toolchains.yml
|
||||
with:
|
||||
cache-key-prefix: ${{github.run_number}}-
|
||||
|
10
.github/workflows/ci-init-script-check.yml
vendored
10
.github/workflows/ci-init-script-check.yml
vendored
@@ -3,9 +3,9 @@ name: CI-init-script-check
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- '.github/workflows/ci-init-script-check.yml'
|
||||
- 'src/resources/init-scripts/**'
|
||||
- 'test/init-script-check/**'
|
||||
- 'test/init-scripts/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@@ -13,14 +13,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
- name: Setup Gradle
|
||||
uses: gradle/gradle-build-action@v2 # Use a released version to avoid breakages
|
||||
uses: gradle/gradle-build-action@v2.11.0 # Use a released version to avoid breakages
|
||||
- name: Run integration tests
|
||||
working-directory: test/init-scripts
|
||||
run: ./gradlew check
|
||||
|
54
.github/workflows/ci-quick-check.yml
vendored
54
.github/workflows/ci-quick-check.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: CI-quick-check
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches-ignore: main
|
||||
|
||||
@@ -9,10 +10,24 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Build and upload distribution
|
||||
uses: ./.github/actions/build-dist
|
||||
|
||||
run-unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure Gradle as default for unit test
|
||||
uses: ./
|
||||
with:
|
||||
gradle-version: 8.5
|
||||
- name: Run tests
|
||||
run: |
|
||||
npm install
|
||||
npm run all
|
||||
|
||||
action-inputs:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-action-inputs.yml
|
||||
@@ -20,9 +35,26 @@ jobs:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
|
||||
cache-cleanup:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-cache-cleanup.yml
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
cache-key-prefix: ${{github.run_number}}- # Requires a fresh cache entry each run
|
||||
|
||||
caching-config:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-action-inputs-caching.yml
|
||||
uses: ./.github/workflows/integ-test-caching-config.yml
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
|
||||
dependency-graph:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-dependency-graph.yml
|
||||
permissions:
|
||||
contents: write
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
@@ -41,6 +73,15 @@ jobs:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
|
||||
gradle-enterprise-injection:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-inject-gradle-enterprise.yml
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
secrets:
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
|
||||
|
||||
provision-gradle-versions:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-provision-gradle-versions.yml
|
||||
@@ -54,6 +95,8 @@ jobs:
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
secrets:
|
||||
GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
|
||||
restore-containerized-gradle-home:
|
||||
needs: build-distribution
|
||||
@@ -94,3 +137,10 @@ jobs:
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
|
||||
toolchain-detection:
|
||||
needs: build-distribution
|
||||
uses: ./.github/workflows/integ-test-detect-java-toolchains.yml
|
||||
with:
|
||||
runner-os: '["ubuntu-latest"]'
|
||||
download-dist: true
|
||||
|
8
.github/workflows/ci-verify-outputs.yml
vendored
8
.github/workflows/ci-verify-outputs.yml
vendored
@@ -15,11 +15,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
npm -v
|
||||
node -v
|
||||
npm install
|
||||
npm run all
|
||||
npm run build
|
||||
|
||||
- name: Compare the expected and actual dist/ directories
|
||||
run: |
|
||||
@@ -31,7 +33,7 @@ jobs:
|
||||
id: diff
|
||||
|
||||
# If index.js was different than expected, upload the expected version as an artifact
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||
with:
|
||||
name: dist
|
||||
|
6
.github/workflows/demo-failure-cases.yml
vendored
6
.github/workflows/demo-failure-cases.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Test build failure
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Test wrapper missing
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Test bad config value
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
|
53
.github/workflows/demo-job-summary.yml
vendored
53
.github/workflows/demo-job-summary.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Demo Job Summary for Gradle builds
|
||||
name: Demo Job Summary, for Gradle builds
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -8,11 +8,11 @@ env:
|
||||
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
|
||||
|
||||
jobs:
|
||||
run-gradle-builds:
|
||||
many-gradle-builds:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Build distribution
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -23,10 +23,10 @@ jobs:
|
||||
- name: Build kotlin-dsl project
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew assemble
|
||||
- name: Build kotlin-dsl project without build scan
|
||||
- name: Build kotlin-dsl project without Build Scan®
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew assemble check --no-scan
|
||||
- name: Build kotlin-dsl project with build scan publish failure
|
||||
- name: Build kotlin-dsl project with Build Scan® publish failure
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew check -Dgradle.enterprise.url=https://not.valid.server
|
||||
- name: Build groovy-dsl project
|
||||
@@ -41,3 +41,46 @@ jobs:
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
continue-on-error: true
|
||||
run: ./gradlew not-a-real-task
|
||||
|
||||
successful-builds-with-no-summary:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Build distribution
|
||||
shell: bash
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
add-job-summary: on-failure
|
||||
- name: Build kotlin-dsl project
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew assemble
|
||||
- name: Build kotlin-dsl project without Build Scan®
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew assemble check --no-scan
|
||||
|
||||
pre-existing-gradle-home:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Build distribution
|
||||
shell: bash
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
- name: Pre-create Gradle User Home
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ~/.gradle
|
||||
mkdir ~/.gradle/caches
|
||||
touch ~/.gradle/caches/dummy.txt
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
- name: Run build
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew assemble
|
||||
|
50
.github/workflows/demo-pr-build-scan-comment.yml
vendored
50
.github/workflows/demo-pr-build-scan-comment.yml
vendored
@@ -1,27 +1,51 @@
|
||||
name: Demo adding build scan comment to PR
|
||||
name: Demo adding Build Scan® comment to PR
|
||||
on:
|
||||
pull_request:
|
||||
types: [assigned, review_requested]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
gradle:
|
||||
successful-build-with-always-comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout project sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
add-job-summary-as-pr-comment: always
|
||||
- name: Run build with Gradle wrapper
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew build --scan
|
||||
- name: "Add build scan URL as PR comment"
|
||||
uses: actions/github-script@v6
|
||||
|
||||
successful-build-with-comment-on-failure:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout project sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: 'PR ready for review: ${{ steps.gradle.outputs.build-scan-url }}'
|
||||
})
|
||||
add-job-summary-as-pr-comment: on-failure
|
||||
- name: Run build with Gradle wrapper
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew build --scan
|
||||
|
||||
failing-build-with-comment-on-failure:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout project sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
add-job-summary-as-pr-comment: on-failure
|
||||
- name: Run build with Gradle wrapper
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew no-a-real-task --scan
|
||||
continue-on-error: true
|
||||
|
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Invoke with multi-line arguments
|
||||
|
87
.github/workflows/integ-test-cache-cleanup.yml
vendored
Normal file
87
.github/workflows/integ-test-cache-cleanup.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
name: Test cache cleanup
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cache-key-prefix:
|
||||
type: string
|
||||
runner-os:
|
||||
type: string
|
||||
default: '["ubuntu-latest", "windows-latest", "macos-latest"]'
|
||||
download-dist:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
env:
|
||||
DOWNLOAD_DIST: ${{ inputs.download-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: integ-test-cache-cleanup-${{ inputs.cache-key-prefix }}
|
||||
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
|
||||
|
||||
jobs:
|
||||
full-build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
- name: Build with 3.1
|
||||
working-directory: test/jest/resources/cache-cleanup
|
||||
run: gradle --no-daemon --build-cache -Dcommons_math3_version="3.1" build
|
||||
|
||||
# Second build will use the cache from the first build, but cleanup should remove unused artifacts
|
||||
assemble-build:
|
||||
needs: full-build
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false
|
||||
gradle-home-cache-cleanup: true
|
||||
- name: Build with 3.1.1
|
||||
working-directory: test/jest/resources/cache-cleanup
|
||||
run: gradle --no-daemon --build-cache -Dcommons_math3_version="3.1.1" build
|
||||
|
||||
check-clean-cache:
|
||||
needs: assemble-build
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: true
|
||||
- name: Report Gradle User Home
|
||||
run: du -hc ~/.gradle/caches/modules-2
|
||||
- name: Verify cleaned cache
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ! -e ~/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-math3/3.1.1 ]; then
|
||||
echo "::error ::Should find commons-math3 3.1.1 in cache"
|
||||
exit 1
|
||||
fi
|
||||
if [ -e ~/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-math3/3.1 ]; then
|
||||
echo "::error ::Should NOT find commons-math3 3.1 in cache"
|
||||
exit 1
|
||||
fi
|
@@ -1,4 +1,4 @@
|
||||
name: Test action inputs for caching
|
||||
name: Test caching configuration
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -38,7 +38,8 @@ jobs:
|
||||
enterprise
|
||||
# Exclude build-cache from main cache entry
|
||||
gradle-home-cache-excludes: |
|
||||
caches/build-cache-1
|
||||
caches/build-cache-*
|
||||
caches/*/executionHistory
|
||||
- name: Build using Gradle wrapper
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew test
|
||||
@@ -52,7 +53,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -63,7 +64,8 @@ jobs:
|
||||
caches
|
||||
enterprise
|
||||
gradle-home-cache-excludes: |
|
||||
caches/build-cache-1
|
||||
caches/build-cache-*
|
||||
caches/*/executionHistory
|
||||
cache-read-only: true
|
||||
- name: Execute Gradle build with --offline
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
@@ -77,7 +79,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -88,19 +90,19 @@ jobs:
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }}
|
||||
run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}"
|
||||
- name: Check build scan url is captured
|
||||
- name: Check Build Scan url is captured
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No build scan detected')
|
||||
core.setFailed('No Build Scan detected')
|
||||
|
||||
# Test that build scans are captured when caching is disabled because Gradle User Home already exists
|
||||
cache-disabled-pre-existing-gradle-home:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Create dummy Gradle User Home
|
||||
@@ -111,12 +113,12 @@ jobs:
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }}
|
||||
run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}"
|
||||
- name: Check build scan url is captured
|
||||
- name: Check Build Scan url is captured
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No build scan detected')
|
||||
core.setFailed('No Build Scan detected')
|
||||
|
||||
# Test seed the cache with cache-write-only and verify with cache-read-only
|
||||
seed-build-write-only:
|
||||
@@ -128,7 +130,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -149,7 +151,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
106
.github/workflows/integ-test-dependency-graph.yml
vendored
Normal file
106
.github/workflows/integ-test-dependency-graph.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
name: Test dependency graph
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cache-key-prefix:
|
||||
type: string
|
||||
runner-os:
|
||||
type: string
|
||||
default: '["ubuntu-latest", "windows-latest", "macos-latest"]'
|
||||
download-dist:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
DOWNLOAD_DIST: ${{ inputs.download-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: dependency-graph-${{ inputs.cache-key-prefix }}
|
||||
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
|
||||
|
||||
jobs:
|
||||
groovy-generate:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle for dependency-graph generate
|
||||
uses: ./
|
||||
with:
|
||||
dependency-graph: generate-and-upload
|
||||
- name: Run gradle build
|
||||
run: ./gradlew build
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
|
||||
kotlin-generate:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle for dependency-graph generate
|
||||
uses: ./
|
||||
with:
|
||||
dependency-graph: generate-and-submit
|
||||
- name: Run gradle build
|
||||
run: ./gradlew build
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
|
||||
submit:
|
||||
needs: [groovy-generate]
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Submit dependency graphs
|
||||
uses: ./
|
||||
with:
|
||||
dependency-graph: download-and-submit
|
||||
|
||||
multiple-builds:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle for dependency-graph generate
|
||||
uses: ./
|
||||
with:
|
||||
dependency-graph: generate-and-submit
|
||||
- id: gradle-assemble
|
||||
run: ./gradlew assemble
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
- id: gradle-build
|
||||
run: ./gradlew build
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
- name: Check generated dependency graphs
|
||||
shell: bash
|
||||
run: |
|
||||
echo "gradle-assemble report file: ${{ steps.gradle-assemble.outputs.dependency-graph-file }}"
|
||||
echo "gradle-build report file: ${{ steps.gradle-build.outputs.dependency-graph-file }}"
|
||||
ls -l dependency-graph-reports
|
||||
if [ ! -e "${{ steps.gradle-assemble.outputs.dependency-graph-file }}" ]; then
|
||||
echo "Did not find gradle-assemble dependency graph file"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -e "${{ steps.gradle-build.outputs.dependency-graph-file }}" ]; then
|
||||
echo "Did not find gradle-build dependency graph files"
|
||||
exit 1
|
||||
fi
|
93
.github/workflows/integ-test-detect-java-toolchains.yml
vendored
Normal file
93
.github/workflows/integ-test-detect-java-toolchains.yml
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
name: Test detect java toolchains
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cache-key-prefix:
|
||||
type: string
|
||||
runner-os:
|
||||
type: string
|
||||
default: '["ubuntu-latest", "windows-latest", "macos-latest"]'
|
||||
download-dist:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
env:
|
||||
DOWNLOAD_DIST: ${{ inputs.download-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: detect-java-toolchain-${{ inputs.cache-key-prefix }}
|
||||
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
|
||||
|
||||
jobs:
|
||||
# Test that pre-installed runner JDKs are detected
|
||||
pre-installed-toolchains:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
- name: List detected toolchains
|
||||
shell: bash
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: |
|
||||
gradle --info javaToolchains > output.txt
|
||||
cat output.txt
|
||||
- name: Verify detected toolchains
|
||||
shell: bash
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: |
|
||||
grep -q 'Eclipse Temurin JDK 1.8' output.txt || (echo "::error::Did not detect preinstalled JDK 1.8" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 11' output.txt || (echo "::error::Did not detect preinstalled JDK 11" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 17' output.txt || (echo "::error::Did not detect preinstalled JDK 17" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 21' output.txt || (echo "::error::Did not detect preinstalled JDK 21" && exit 1)
|
||||
|
||||
# Test that JDKs provisioned by setup-java are detected
|
||||
setup-java-installed-toolchain:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Java 20
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '20'
|
||||
- name: Setup Java 16
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '16'
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
- name: List detected toolchains
|
||||
shell: bash
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: |
|
||||
gradle --info javaToolchains > output.txt
|
||||
cat output.txt
|
||||
- name: Verify setup JDKs are detected
|
||||
shell: bash
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: |
|
||||
grep -q 'Eclipse Temurin JDK 16' output.txt || (echo "::error::Did not detect setup-java installed JDK 16" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 20' output.txt || (echo "::error::Did not detect setup-java installed JDK 20" && exit 1)
|
||||
- name: Verify pre-installed toolchains are detected
|
||||
shell: bash
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: |
|
||||
grep -q 'Eclipse Temurin JDK 1.8' output.txt || (echo "::error::Did not detect preinstalled JDK 1.8" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 11' output.txt || (echo "::error::Did not detect preinstalled JDK 11" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 17' output.txt || (echo "::error::Did not detect preinstalled JDK 17" && exit 1)
|
||||
grep -q 'Eclipse Temurin JDK 21' output.txt || (echo "::error::Did not detect preinstalled JDK 21" && exit 1)
|
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Execute Gradle build
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Execute Gradle build
|
||||
|
12
.github/workflows/integ-test-execution.yml
vendored
12
.github/workflows/integ-test-execution.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Test use defined Gradle version
|
||||
@@ -68,11 +68,11 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
@@ -84,11 +84,11 @@ jobs:
|
||||
gradle-version: ${{matrix.gradle}}
|
||||
build-root-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }}
|
||||
arguments: help -DgradleVersionCheck=${{matrix.gradle}}
|
||||
- name: Check build scan url
|
||||
- name: Check Build Scan url
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No build scan detected')
|
||||
core.setFailed('No Build Scan detected')
|
||||
|
||||
|
||||
|
60
.github/workflows/integ-test-inject-gradle-enterprise.yml
vendored
Normal file
60
.github/workflows/integ-test-inject-gradle-enterprise.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: Test gradle enterprise injection
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cache-key-prefix:
|
||||
type: string
|
||||
runner-os:
|
||||
type: string
|
||||
default: '["ubuntu-latest", "windows-latest", "macos-latest"]'
|
||||
download-dist:
|
||||
type: boolean
|
||||
default: false
|
||||
secrets:
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY:
|
||||
required: true
|
||||
|
||||
env:
|
||||
DOWNLOAD_DIST: ${{ inputs.download-dist }}
|
||||
GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: provision-gradle-versions-${{ inputs.cache-key-prefix }}
|
||||
GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
|
||||
GRADLE_ENTERPRISE_INJECTION_ENABLED: true
|
||||
GRADLE_ENTERPRISE_URL: https://ge.solutions-team.gradle.com
|
||||
GRADLE_ENTERPRISE_PLUGIN_VERSION: 3.16.1
|
||||
GRADLE_ENTERPRISE_CCUD_PLUGIN_VERSION: 1.12.1
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
|
||||
|
||||
jobs:
|
||||
inject-gradle-enterprise:
|
||||
strategy:
|
||||
matrix:
|
||||
gradle: [current, 7.6.2, 6.9.4, 5.6.4]
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
gradle-version: ${{ matrix.gradle }}
|
||||
- name: Run Gradle build
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-ge
|
||||
run: gradle help
|
||||
- name: Check Build Scan url
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No Build Scan detected')
|
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle with v6.9
|
||||
@@ -55,6 +55,17 @@ jobs:
|
||||
- name: Test use release-candidate
|
||||
working-directory: .github/workflow-samples/no-wrapper
|
||||
run: gradle help
|
||||
- name: Setup Gradle with current
|
||||
id: gradle-current
|
||||
uses: ./
|
||||
with:
|
||||
gradle-version: current
|
||||
- name: Check current version output parameter
|
||||
if: ${{ !startsWith(steps.gradle-current.outputs.gradle-version , '8.') }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('Gradle version parameter not set correctly: value was "${{ steps.gradle-current.outputs.gradle-version }}"')
|
||||
|
||||
gradle-versions:
|
||||
strategy:
|
||||
@@ -71,28 +82,35 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 8
|
||||
- name: Setup Gradle
|
||||
id: setup-gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
gradle-version: ${{ matrix.gradle }}
|
||||
- name: Check output parameter
|
||||
if: ${{ steps.setup-gradle.outputs.gradle-version != matrix.gradle }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('Gradle version parameter not set correctly: value was "${{ steps.setup-gradle.outputs.gradle-version }}"')
|
||||
- name: Run Gradle build
|
||||
id: gradle
|
||||
working-directory: .github/workflow-samples/no-wrapper${{ matrix.build-root-suffix }}
|
||||
run: gradle help "-DgradleVersionCheck=${{matrix.gradle}}"
|
||||
- name: Check build scan url
|
||||
- name: Check Build Scan url
|
||||
if: ${{ !steps.gradle.outputs.build-scan-url }}
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('No build scan detected')
|
||||
core.setFailed('No Build Scan detected')
|
||||
|
||||
|
||||
|
@@ -11,6 +11,9 @@ on:
|
||||
download-dist:
|
||||
type: boolean
|
||||
default: false
|
||||
secrets:
|
||||
GRADLE_ENCRYPTION_KEY:
|
||||
required: true
|
||||
|
||||
env:
|
||||
DOWNLOAD_DIST: ${{ inputs.download-dist }}
|
||||
@@ -27,16 +30,18 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
gradle-version: 8.6-rc-1
|
||||
- name: Groovy build with configuration-cache enabled
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew test --configuration-cache
|
||||
run: gradle test --configuration-cache
|
||||
|
||||
verify-build-groovy:
|
||||
env:
|
||||
@@ -48,23 +53,27 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: true
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
gradle-version: 8.6-rc-1
|
||||
- name: Groovy build with configuration-cache enabled
|
||||
id: execute
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew test --configuration-cache
|
||||
run: gradle test --configuration-cache
|
||||
- name: Check that configuration-cache was used
|
||||
if: ${{ steps.execute.outputs.task_configured == 'yes' }}
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('Configuration cache was not used - task was configured unexpectedly')
|
||||
const fs = require('fs')
|
||||
if (fs.existsSync('.github/workflow-samples/groovy-dsl/task-configured.txt')) {
|
||||
core.setFailed('Configuration cache was not used - task was configured unexpectedly')
|
||||
}
|
||||
|
||||
# Check that the build can run when no extracted cache entries are restored
|
||||
gradle-user-home-not-fully-restored:
|
||||
@@ -77,7 +86,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle with no extracted cache entries restored
|
||||
@@ -86,9 +95,11 @@ jobs:
|
||||
GRADLE_BUILD_ACTION_SKIP_RESTORE: "generated-gradle-jars|wrapper-zips|java-toolchains|instrumented-jars|dependencies|kotlin-dsl"
|
||||
with:
|
||||
cache-read-only: true
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
gradle-version: 8.6-rc-1
|
||||
- name: Check execute Gradle build with configuration cache enabled (but not restored)
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew test --configuration-cache
|
||||
run: gradle test --configuration-cache
|
||||
|
||||
seed-build-kotlin:
|
||||
env:
|
||||
@@ -99,16 +110,18 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
gradle-version: 8.6-rc-1
|
||||
- name: Execute 'help' with configuration-cache enabled
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew help --configuration-cache
|
||||
run: gradle help --configuration-cache
|
||||
|
||||
modify-build-kotlin:
|
||||
env:
|
||||
@@ -120,16 +133,18 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
gradle-version: 8.6-rc-1
|
||||
- name: Execute 'test' with configuration-cache enabled
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew test --configuration-cache
|
||||
run: gradle test --configuration-cache
|
||||
|
||||
# Test restore configuration-cache from the third build invocation
|
||||
verify-build-kotlin:
|
||||
@@ -142,21 +157,25 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: true
|
||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||
gradle-version: 8.6-rc-1
|
||||
- name: Execute 'test' again with configuration-cache enabled
|
||||
id: execute
|
||||
working-directory: .github/workflow-samples/kotlin-dsl
|
||||
run: ./gradlew test --configuration-cache
|
||||
run: gradle test --configuration-cache
|
||||
- name: Check that configuration-cache was used
|
||||
if: ${{ steps.execute.outputs.task_configured == 'yes' }}
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.setFailed('Configuration cache was not used - task was configured unexpectedly')
|
||||
const fs = require('fs')
|
||||
if (fs.existsSync('.github/workflow-samples/kotlin-dsl/task-configured.txt')) {
|
||||
core.setFailed('Configuration cache was not used - task was configured unexpectedly')
|
||||
}
|
||||
|
||||
|
@@ -20,11 +20,11 @@ jobs:
|
||||
container: fedora:latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: temurin
|
||||
@@ -43,11 +43,11 @@ jobs:
|
||||
container: fedora:latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: temurin
|
||||
|
@@ -23,7 +23,7 @@ jobs:
|
||||
mkdir -p $GITHUB_WORKSPACE/gradle-user-home
|
||||
echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
mkdir -p $GITHUB_WORKSPACE/gradle-user-home
|
||||
echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
mkdir -p $GITHUB_WORKSPACE/gradle-user-home
|
||||
echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/gradle-user-home" >> $GITHUB_ENV
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
|
@@ -26,7 +26,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle with no extracted cache entries restored
|
||||
@@ -99,3 +99,40 @@ jobs:
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew test
|
||||
|
||||
# Test that a pre-existing gradle-user-home can be overwritten by the restored cache
|
||||
pre-existing-gradle-home:
|
||||
needs: seed-build
|
||||
strategy:
|
||||
matrix:
|
||||
os: ${{fromJSON(inputs.runner-os)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Pre-create Gradle User Home
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ~/.gradle/caches
|
||||
touch ~/.gradle/gradle.properties
|
||||
touch ~/.gradle/caches/dummy.txt
|
||||
- name: Setup Gradle
|
||||
uses: ./
|
||||
with:
|
||||
cache-read-only: true
|
||||
cache-overwrite-existing: true
|
||||
- name: Check that pre-existing content still exists
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ! -e ~/.gradle/caches/dummy.txt ]; then
|
||||
echo "::error ::Should find dummy.txt after cache restore"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -e ~/.gradle/gradle.properties ]; then
|
||||
echo "::error ::Should find gradle.properties after cache restore"
|
||||
exit 1
|
||||
fi
|
||||
- name: Execute Gradle build with --offline
|
||||
working-directory: .github/workflow-samples/groovy-dsl
|
||||
run: ./gradlew test --offline
|
||||
|
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
|
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
|
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Download distribution if required
|
||||
uses: ./.github/actions/download-dist
|
||||
- name: Setup Gradle
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -102,5 +102,3 @@ __tests__/runner/*
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# ASDF tool configuration
|
||||
.tool-versions
|
||||
|
3
.tool-versions
Normal file
3
.tool-versions
Normal file
@@ -0,0 +1,3 @@
|
||||
# Configuration file for asdf version manager
|
||||
nodejs 20.10.0
|
||||
gradle 8.5
|
14
CONTRIBUTING.md
Normal file
14
CONTRIBUTING.md
Normal file
@@ -0,0 +1,14 @@
|
||||
### How to merge a Dependabot PR
|
||||
|
||||
The "distribution" for a GitHub Action is checked into the repository itself.
|
||||
In the case of the `gradle-build-action`, the transpiled sources are committed to the `dist` directory.
|
||||
Any production dependencies are inlined into the distribution.
|
||||
So if a Dependabot PR updates a production dependency (or a dev dependency that changes the distribution, like the Typescript compiler),
|
||||
then a manual step is required to rebuild the dist and commit.
|
||||
|
||||
The simplest process to follow is:
|
||||
1. Checkout the dependabot branch locally eg: `git checkout dependabot/npm_and_yarn/actions/github-5.1.0`
|
||||
2. Run `npm install` to download and the new dependencies and install locally
|
||||
3. Run `npm run build` to regenerate the distribution
|
||||
4. Push the changes to the dependabot branch
|
||||
5. If/when the checks pass, you can merge the dependabot PR
|
2
LICENSE
2
LICENSE
@@ -1,7 +1,7 @@
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 GitHub, Inc. and contributors
|
||||
Copyright (c) 2023 Gradle Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
69
action.yml
69
action.yml
@@ -1,11 +1,11 @@
|
||||
name: "Gradle Build Action"
|
||||
description: 'Configures Gradle for use in GitHub actions, caching useful state in the GitHub actions cache'
|
||||
description: 'Configures Gradle for GitHub actions, caching state and generating a dependency graph via Dependency Submission.'
|
||||
|
||||
# https://help.github.com/en/articles/metadata-syntax-for-github-actions
|
||||
|
||||
inputs:
|
||||
gradle-version:
|
||||
description: Gradle version to use
|
||||
description: Gradle version to use. If specified, this Gradle version will be downloaded, added to the PATH and used for invoking Gradle.
|
||||
required: false
|
||||
|
||||
cache-disabled:
|
||||
@@ -18,7 +18,7 @@ inputs:
|
||||
When 'true', existing entries will be read from the cache but no entries will be written.
|
||||
By default this value is 'false' for workflows on the GitHub default branch and 'true' for workflows on other branches.
|
||||
required: false
|
||||
default: ${{ github.event.repository && github.ref_name != github.event.repository.default_branch }}
|
||||
default: ${{ github.event.repository != null && github.ref_name != github.event.repository.default_branch }}
|
||||
|
||||
cache-write-only:
|
||||
description: |
|
||||
@@ -27,6 +27,18 @@ inputs:
|
||||
required: false
|
||||
default: false
|
||||
|
||||
cache-overwrite-existing:
|
||||
description: When 'true', a pre-existing Gradle User Home will not prevent the cache from being restored.
|
||||
required: false
|
||||
default: false
|
||||
|
||||
cache-encryption-key:
|
||||
description: |
|
||||
A base64 encoded AES key used to encrypt the configuration-cache data. The key is exported as 'GRADLE_ENCRYPTION_KEY' for later steps.
|
||||
A suitable key can be generated with `openssl rand -base64 16`.
|
||||
Configuration-cache data will not be saved/restored without an encryption key being provided.
|
||||
required: false
|
||||
|
||||
gradle-home-cache-includes:
|
||||
description: Paths within Gradle User Home to cache.
|
||||
required: false
|
||||
@@ -41,22 +53,51 @@ inputs:
|
||||
# gradle-home-cache-excludes: |
|
||||
# caches/build-cache-1
|
||||
|
||||
gradle-home-cache-cleanup:
|
||||
description: When 'true', the action will attempt to remove any stale/unused entries from the Gradle User Home prior to saving to the GitHub Actions cache.
|
||||
required: false
|
||||
default: false
|
||||
|
||||
add-job-summary:
|
||||
description: Specifies when a Job Summary should be inluded in the action results. Valid values are 'never', 'always' (default), and 'on-failure'.
|
||||
required: false
|
||||
default: 'always'
|
||||
|
||||
add-job-summary-as-pr-comment:
|
||||
description: Specifies when each Job Summary should be added as a PR comment. Valid values are 'never' (default), 'always', and 'on-failure'. No action will be taken if the workflow was not triggered from a pull request.
|
||||
required: false
|
||||
default: 'never'
|
||||
|
||||
dependency-graph:
|
||||
description: Specifies if a GitHub dependency snapshot should be generated for each Gradle build, and if so, how. Valid values are 'disabled' (default), 'generate', 'generate-and-submit', 'generate-and-upload' and 'download-and-submit'.
|
||||
required: false
|
||||
default: 'disabled'
|
||||
|
||||
artifact-retention-days:
|
||||
description: Specifies the number of days to retain any artifacts generated by the action. If not set, the default retention settings for the repository will apply.
|
||||
required: false
|
||||
|
||||
# DEPRECATED ACTION INPUTS
|
||||
arguments:
|
||||
description: Gradle command line arguments (supports multi-line input)
|
||||
required: false
|
||||
deprecation-message: Using the action to execute Gradle directly is deprecated in favor of using the action to setup Gradle, and executing Gradle in a subsequent Step. See https://github.com/gradle/gradle-build-action?tab=readme-ov-file#use-the-action-to-setup-gradle.
|
||||
|
||||
build-root-directory:
|
||||
description: Path to the root directory of the build
|
||||
description: Path to the root directory of the build. Default is the root of the GitHub workspace.
|
||||
required: false
|
||||
deprecation-message: Using the action to execute Gradle directly is deprecated in favor of using the action to setup Gradle, and executing Gradle in a subsequent Step. See https://github.com/gradle/gradle-build-action?tab=readme-ov-file#use-the-action-to-setup-gradle.
|
||||
|
||||
gradle-executable:
|
||||
description: Path to the Gradle executable
|
||||
description: Path to the Gradle executable. If specified, this executable will be added to the PATH and used for invoking Gradle.
|
||||
required: false
|
||||
deprecation-message: Using the action to execute Gradle directly is deprecated in favor of using the action to setup Gradle, and executing Gradle in a subsequent Step. See https://github.com/gradle/gradle-build-action?tab=readme-ov-file#use-the-action-to-setup-gradle.
|
||||
|
||||
generate-job-summary:
|
||||
description: When 'false', no Job Summary will be generated for the Job.
|
||||
required: false
|
||||
default: true
|
||||
deprecation-message: Superceded by the new 'add-job-summary' and 'add-job-summary-as-pr-comment' parameters.
|
||||
|
||||
# EXPERIMENTAL & INTERNAL ACTION INPUTS
|
||||
# The following action properties allow fine-grained tweaking of the action caching behaviour.
|
||||
@@ -66,21 +107,27 @@ inputs:
|
||||
description: When 'true', the action will not attempt to restore the Gradle User Home entries from other Jobs.
|
||||
required: false
|
||||
default: false
|
||||
cache-read-timeout:
|
||||
description: A timeout value in seconds for cache reads. Requests taking longer that this will be aborted.
|
||||
required: true
|
||||
default: 600
|
||||
|
||||
workflow-job-context:
|
||||
description: Used to uniquely identify the current job invocation. Defaults to the matrix values for this job; this should not be overridden by users (INTERNAL).
|
||||
required: false
|
||||
default: ${{ toJSON(matrix) }}
|
||||
|
||||
github-token:
|
||||
description: The GitHub token used to authenticate when submitting via the Dependency Submission API.
|
||||
default: ${{ github.token }}
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
build-scan-url:
|
||||
description: Link to the build scan if any
|
||||
description: Link to the Build Scan® generated by a Gradle build. Note that this output applies to a Step executing Gradle, not to the `gradle-build-action` Step itself.
|
||||
dependency-graph-file:
|
||||
description: Path to the GitHub Dependency Graph snapshot file generated by a Gradle build. Note that this output applies to a Step executing Gradle, not to the `gradle-build-action` Step itself.
|
||||
gradle-version:
|
||||
description: Version of Gradle that was setup by the action
|
||||
|
||||
runs:
|
||||
using: 'node16'
|
||||
using: 'node20'
|
||||
main: 'dist/main/index.js'
|
||||
post: 'dist/post/index.js'
|
||||
|
||||
|
24
actions/clear-dependency-graph/action.yml
Normal file
24
actions/clear-dependency-graph/action.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
name: 'Clear dependency graph for a correlator'
|
||||
|
||||
inputs:
|
||||
job-correlator:
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Set current timestamp as env variable
|
||||
shell: bash
|
||||
run: echo "NOW=$(date -Iseconds)" >> $GITHUB_ENV
|
||||
- name: Submit empty dependency graph
|
||||
shell: bash
|
||||
run: |
|
||||
curl -L \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer ${{ github.token }}" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/repos/${{ github.repository }}/dependency-graph/snapshots \
|
||||
-d '{ "version" : 0, "job" : { "id" : "${{ github.run_id }}", "correlator" : "${{ inputs.job-correlator }} " }, "sha" : "${{ github.sha }}", "ref" : "${{ github.ref }}", "detector" : { "name" : "GitHub Dependency Graph Gradle Plugin", "version" : "0.0.3", "url" : "https://github.com/gradle/github-dependency-graph-gradle-plugin" }, "manifests" : {}, "scanned" : "${{ env.NOW }}" }'
|
||||
- run: echo "::notice ::Cleared dependency graph for job correlator '${{ inputs.job-correlator }}'"
|
||||
shell: bash
|
96244
dist/main/index.js
vendored
96244
dist/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/main/index.js.map
vendored
2
dist/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
1
dist/main/sourcemap-register.js
vendored
1
dist/main/sourcemap-register.js
vendored
File diff suppressed because one or more lines are too long
94371
dist/post/index.js
vendored
94371
dist/post/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/post/index.js.map
vendored
2
dist/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
1
dist/post/sourcemap-register.js
vendored
1
dist/post/sourcemap-register.js
vendored
File diff suppressed because one or more lines are too long
9843
package-lock.json
generated
9843
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
50
package.json
50
package.json
@@ -8,10 +8,13 @@
|
||||
"format": "prettier --write **/*.ts",
|
||||
"format-check": "prettier --check **/*.ts",
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"build": "ncc build src/main.ts --out dist/main --source-map && ncc build src/post.ts --out dist/post --source-map",
|
||||
"compile-main": "ncc build src/main.ts --out dist/main --source-map --no-source-map-register",
|
||||
"compile-post": "ncc build src/post.ts --out dist/post --source-map --no-source-map-register",
|
||||
"compile": "npm run compile-main && npm run compile-post",
|
||||
"test": "jest",
|
||||
"check": "npm run format && npm run lint",
|
||||
"all": "npm run format && npm run lint && npm run build && npm test"
|
||||
"build": "npm run check && npm run compile",
|
||||
"all": "npm run build && npm test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,29 +28,34 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "3.0.3",
|
||||
"@actions/core": "1.9.1",
|
||||
"@actions/artifact": "2.0.0",
|
||||
"@actions/cache": "3.2.2",
|
||||
"@actions/core": "1.10.1",
|
||||
"@actions/exec": "1.1.1",
|
||||
"@actions/github": "5.0.3",
|
||||
"@actions/glob": "0.3.0",
|
||||
"@actions/http-client": "2.0.1",
|
||||
"@actions/github": "6.0.0",
|
||||
"@actions/glob": "0.4.0",
|
||||
"@actions/http-client": "2.2.0",
|
||||
"@actions/tool-cache": "2.0.1",
|
||||
"string-argv": "0.3.1"
|
||||
"@octokit/rest": "19.0.13",
|
||||
"@octokit/webhooks-types": "7.3.1",
|
||||
"semver": "7.5.4",
|
||||
"string-argv": "0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "28.1.7",
|
||||
"@types/node": "16.11.21",
|
||||
"@types/unzipper": "0.10.5",
|
||||
"@typescript-eslint/parser": "5.33.1",
|
||||
"@vercel/ncc": "0.34.0",
|
||||
"eslint": "8.22.0",
|
||||
"eslint-plugin-github": "4.3.7",
|
||||
"eslint-plugin-jest": "26.8.3",
|
||||
"jest": "28.1.3",
|
||||
"@types/jest": "29.5.11",
|
||||
"@types/node": "20.10.0",
|
||||
"@types/unzipper": "0.10.9",
|
||||
"@typescript-eslint/parser": "6.17.0",
|
||||
"@vercel/ncc": "0.38.1",
|
||||
"eslint": "8.56.0",
|
||||
"eslint-plugin-github": "4.10.1",
|
||||
"eslint-plugin-jest": "27.6.1",
|
||||
"eslint-plugin-prettier": "5.1.2",
|
||||
"jest": "29.7.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"patch-package": "6.4.7",
|
||||
"prettier": "2.7.1",
|
||||
"ts-jest": "28.0.8",
|
||||
"typescript": "4.7.4"
|
||||
"patch-package": "8.0.0",
|
||||
"prettier": "3.1.1",
|
||||
"ts-jest": "29.1.1",
|
||||
"typescript": "5.3.3"
|
||||
}
|
||||
}
|
||||
|
@@ -1,22 +1,22 @@
|
||||
diff --git a/node_modules/@actions/cache/lib/cache.d.ts b/node_modules/@actions/cache/lib/cache.d.ts
|
||||
index 16b20f7..aea77ba 100644
|
||||
index 4658366..b796e58 100644
|
||||
--- a/node_modules/@actions/cache/lib/cache.d.ts
|
||||
+++ b/node_modules/@actions/cache/lib/cache.d.ts
|
||||
@@ -20,7 +20,7 @@ export declare function isFeatureAvailable(): boolean;
|
||||
* @param downloadOptions cache download options
|
||||
@@ -21,7 +21,7 @@ export declare function isFeatureAvailable(): boolean;
|
||||
* @param enableCrossOsArchive an optional boolean enabled to restore on windows any cache created on any platform
|
||||
* @returns string returns the key for the cache hit, otherwise returns undefined
|
||||
*/
|
||||
-export declare function restoreCache(paths: string[], primaryKey: string, restoreKeys?: string[], options?: DownloadOptions): Promise<string | undefined>;
|
||||
+export declare function restoreCache(paths: string[], primaryKey: string, restoreKeys?: string[], options?: DownloadOptions): Promise<CacheEntry | undefined>;
|
||||
-export declare function restoreCache(paths: string[], primaryKey: string, restoreKeys?: string[], options?: DownloadOptions, enableCrossOsArchive?: boolean): Promise<string | undefined>;
|
||||
+export declare function restoreCache(paths: string[], primaryKey: string, restoreKeys?: string[], options?: DownloadOptions, enableCrossOsArchive?: boolean): Promise<CacheEntry | undefined>;
|
||||
/**
|
||||
* Saves a list of files with the specified key
|
||||
*
|
||||
@@ -29,4 +29,12 @@ export declare function restoreCache(paths: string[], primaryKey: string, restor
|
||||
@@ -31,4 +31,12 @@ export declare function restoreCache(paths: string[], primaryKey: string, restor
|
||||
* @param options cache upload options
|
||||
* @returns number returns cacheId if the cache was saved successfully and throws an error if save fails
|
||||
*/
|
||||
-export declare function saveCache(paths: string[], key: string, options?: UploadOptions): Promise<number>;
|
||||
+export declare function saveCache(paths: string[], key: string, options?: UploadOptions): Promise<CacheEntry>;
|
||||
-export declare function saveCache(paths: string[], key: string, options?: UploadOptions, enableCrossOsArchive?: boolean): Promise<number>;
|
||||
+export declare function saveCache(paths: string[], key: string, options?: UploadOptions, enableCrossOsArchive?: boolean): Promise<CacheEntry>;
|
||||
+
|
||||
+// PATCHED: Add `CacheEntry` as return type for save/restore functions
|
||||
+// This allows us to track and report on cache entry sizes.
|
||||
@@ -26,23 +26,12 @@ index 16b20f7..aea77ba 100644
|
||||
+ constructor(key: string, size?: number);
|
||||
+}
|
||||
diff --git a/node_modules/@actions/cache/lib/cache.js b/node_modules/@actions/cache/lib/cache.js
|
||||
index 4dc5e88..92d99d5 100644
|
||||
index 9d636aa..a176bd7 100644
|
||||
--- a/node_modules/@actions/cache/lib/cache.js
|
||||
+++ b/node_modules/@actions/cache/lib/cache.js
|
||||
@@ -95,26 +95,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
|
||||
}
|
||||
archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
|
||||
core.debug(`Archive Path: ${archivePath}`);
|
||||
+ const restoredEntry = new CacheEntry(cacheEntry.cacheKey);
|
||||
// Download the cache from the cache entry
|
||||
yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options);
|
||||
if (core.isDebug()) {
|
||||
yield tar_1.listTar(archivePath, compressionMethod);
|
||||
}
|
||||
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||
+ restoredEntry.size = archiveFileSize;
|
||||
@@ -127,18 +127,21 @@ function restoreCache(paths, primaryKey, restoreKeys, options, enableCrossOsArch
|
||||
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
|
||||
yield tar_1.extractTar(archivePath, compressionMethod);
|
||||
yield (0, tar_1.extractTar)(archivePath, compressionMethod);
|
||||
core.info('Cache restored successfully');
|
||||
- return cacheEntry.cacheKey;
|
||||
- }
|
||||
@@ -55,29 +44,31 @@ index 4dc5e88..92d99d5 100644
|
||||
- // Supress all non-validation cache related errors because caching should be optional
|
||||
- core.warning(`Failed to restore: ${error.message}`);
|
||||
- }
|
||||
+ return restoredEntry;
|
||||
+
|
||||
+ // PATCHED - Return more inforamtion about restored entry
|
||||
+ return new CacheEntry(cacheEntry.cacheKey, archiveFileSize);;
|
||||
}
|
||||
+ // PATCHED - propagate errors
|
||||
+ // catch (error) {
|
||||
+ // const typedError = error;
|
||||
+ // if (typedError.name === ValidationError.name) {
|
||||
+ // throw error;
|
||||
+ // }
|
||||
+ // else {
|
||||
+ // // Supress all non-validation cache related errors because caching should be optional
|
||||
+ // core.warning(`Failed to restore: ${error.message}`);
|
||||
+ // }
|
||||
+ // }
|
||||
finally {
|
||||
// Try to delete the archive to save space
|
||||
@@ -153,6 +145,7 @@ function saveCache(paths, key, options) {
|
||||
const archiveFolder = yield utils.createTempDirectory();
|
||||
const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod));
|
||||
core.debug(`Archive Path: ${archivePath}`);
|
||||
+ const savedEntry = new CacheEntry(key);
|
||||
try {
|
||||
yield tar_1.createTar(archiveFolder, cachePaths, compressionMethod);
|
||||
if (core.isDebug()) {
|
||||
@@ -160,6 +153,7 @@ function saveCache(paths, key, options) {
|
||||
try {
|
||||
@@ -206,19 +209,23 @@ function saveCache(paths, key, options, enableCrossOsArchive = false) {
|
||||
}
|
||||
const fileSizeLimit = 10 * 1024 * 1024 * 1024; // 10GB per repo limit
|
||||
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath);
|
||||
+ savedEntry.size = archiveFileSize;
|
||||
core.debug(`File Size: ${archiveFileSize}`);
|
||||
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
|
||||
if (archiveFileSize > fileSizeLimit && !utils.isGhes()) {
|
||||
@@ -182,18 +176,6 @@ function saveCache(paths, key, options) {
|
||||
core.debug(`Saving Cache (ID: ${cacheId})`);
|
||||
yield cacheHttpClient.saveCache(cacheId, archivePath, options);
|
||||
+
|
||||
+ // PATCHED - Return more inforamtion about saved entry
|
||||
+ return new CacheEntry(key, archiveFileSize);
|
||||
}
|
||||
- catch (error) {
|
||||
- const typedError = error;
|
||||
@@ -91,15 +82,23 @@ index 4dc5e88..92d99d5 100644
|
||||
- core.warning(`Failed to save: ${typedError.message}`);
|
||||
- }
|
||||
- }
|
||||
+ // PATCHED - propagate errors
|
||||
+ // catch (error) {
|
||||
+ // const typedError = error;
|
||||
+ // if (typedError.name === ValidationError.name) {
|
||||
+ // throw error;
|
||||
+ // }
|
||||
+ // else if (typedError.name === ReserveCacheError.name) {
|
||||
+ // core.info(`Failed to save: ${typedError.message}`);
|
||||
+ // }
|
||||
+ // else {
|
||||
+ // core.warning(`Failed to save: ${typedError.message}`);
|
||||
+ // }
|
||||
+ // }
|
||||
finally {
|
||||
// Try to delete the archive to save space
|
||||
try {
|
||||
@@ -203,8 +185,15 @@ function saveCache(paths, key, options) {
|
||||
core.debug(`Failed to delete archive: ${error}`);
|
||||
}
|
||||
}
|
||||
- return cacheId;
|
||||
+ return savedEntry;
|
||||
@@ -232,4 +239,11 @@ function saveCache(paths, key, options, enableCrossOsArchive = false) {
|
||||
});
|
||||
}
|
||||
exports.saveCache = saveCache;
|
48
patches/@azure+logger+1.0.4.patch
Normal file
48
patches/@azure+logger+1.0.4.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
diff --git a/node_modules/@azure/logger/dist-esm/src/debug.js b/node_modules/@azure/logger/dist-esm/src/debug.js
|
||||
index d202779..30e8313 100644
|
||||
--- a/node_modules/@azure/logger/dist-esm/src/debug.js
|
||||
+++ b/node_modules/@azure/logger/dist-esm/src/debug.js
|
||||
@@ -7,7 +7,7 @@ let enabledNamespaces = [];
|
||||
let skippedNamespaces = [];
|
||||
const debuggers = [];
|
||||
if (debugEnvVariable) {
|
||||
- enable(debugEnvVariable);
|
||||
+ // enable(debugEnvVariable);
|
||||
}
|
||||
const debugObj = Object.assign((namespace) => {
|
||||
return createDebugger(namespace);
|
||||
diff --git a/node_modules/@azure/logger/dist-esm/src/index.js b/node_modules/@azure/logger/dist-esm/src/index.js
|
||||
index cc25720..2925db5 100644
|
||||
--- a/node_modules/@azure/logger/dist-esm/src/index.js
|
||||
+++ b/node_modules/@azure/logger/dist-esm/src/index.js
|
||||
@@ -20,7 +20,7 @@ if (logLevelFromEnv) {
|
||||
setLogLevel(logLevelFromEnv);
|
||||
}
|
||||
else {
|
||||
- console.error(`AZURE_LOG_LEVEL set to unknown log level '${logLevelFromEnv}'; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
|
||||
+ console.error(`AZURE_LOG_LEVEL set to unknown log level; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
diff --git a/node_modules/@azure/logger/dist/index.js b/node_modules/@azure/logger/dist/index.js
|
||||
index 81e97c3..a415e2f 100644
|
||||
--- a/node_modules/@azure/logger/dist/index.js
|
||||
+++ b/node_modules/@azure/logger/dist/index.js
|
||||
@@ -21,7 +21,7 @@ let enabledNamespaces = [];
|
||||
let skippedNamespaces = [];
|
||||
const debuggers = [];
|
||||
if (debugEnvVariable) {
|
||||
- enable(debugEnvVariable);
|
||||
+ // enable(debugEnvVariable);
|
||||
}
|
||||
const debugObj = Object.assign((namespace) => {
|
||||
return createDebugger(namespace);
|
||||
@@ -125,7 +125,7 @@ if (logLevelFromEnv) {
|
||||
setLogLevel(logLevelFromEnv);
|
||||
}
|
||||
else {
|
||||
- console.error(`AZURE_LOG_LEVEL set to unknown log level '${logLevelFromEnv}'; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
|
||||
+ console.error(`AZURE_LOG_LEVEL set to unknown log level; logging is not enabled. Acceptable values: ${AZURE_LOG_LEVELS.join(", ")}.`);
|
||||
}
|
||||
}
|
||||
/**
|
@@ -1,37 +1,40 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as glob from '@actions/glob'
|
||||
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import * as params from './input-params'
|
||||
import {CacheListener} from './cache-reporting'
|
||||
import {saveCache, restoreCache, cacheDebug, isCacheDebuggingEnabled, tryDelete, generateCacheKey} from './cache-utils'
|
||||
import {ConfigurationCacheEntryExtractor, GradleHomeEntryExtractor} from './cache-extract-entries'
|
||||
import {GradleHomeEntryExtractor, ConfigurationCacheEntryExtractor} from './cache-extract-entries'
|
||||
|
||||
const RESTORED_CACHE_KEY_KEY = 'restored-cache-key'
|
||||
|
||||
export const META_FILE_DIR = '.gradle-build-action'
|
||||
const INCLUDE_PATHS_PARAMETER = 'gradle-home-cache-includes'
|
||||
const EXCLUDE_PATHS_PARAMETER = 'gradle-home-cache-excludes'
|
||||
|
||||
export class GradleStateCache {
|
||||
private cacheName: string
|
||||
private cacheDescription: string
|
||||
|
||||
protected readonly userHome: string
|
||||
protected readonly gradleUserHome: string
|
||||
|
||||
constructor(gradleUserHome: string) {
|
||||
constructor(userHome: string, gradleUserHome: string) {
|
||||
this.userHome = userHome
|
||||
this.gradleUserHome = gradleUserHome
|
||||
this.cacheName = 'gradle'
|
||||
this.cacheDescription = 'Gradle User Home'
|
||||
}
|
||||
|
||||
init(): void {
|
||||
const actionCacheDir = path.resolve(this.gradleUserHome, '.gradle-build-action')
|
||||
fs.mkdirSync(actionCacheDir, {recursive: true})
|
||||
this.initializeGradleUserHome()
|
||||
|
||||
const initScriptsDir = path.resolve(this.gradleUserHome, 'init.d')
|
||||
fs.mkdirSync(initScriptsDir, {recursive: true})
|
||||
|
||||
this.initializeGradleUserHome(this.gradleUserHome, initScriptsDir)
|
||||
// Export the GRADLE_ENCRYPTION_KEY variable if provided
|
||||
const encryptionKey = params.getCacheEncryptionKey()
|
||||
if (encryptionKey) {
|
||||
core.exportVariable('GRADLE_ENCRYPTION_KEY', encryptionKey)
|
||||
}
|
||||
}
|
||||
|
||||
cacheOutputExists(): boolean {
|
||||
@@ -128,7 +131,7 @@ export class GradleStateCache {
|
||||
*/
|
||||
async beforeSave(listener: CacheListener): Promise<void> {
|
||||
await this.debugReportGradleUserHomeSize('before saving common artifacts')
|
||||
this.deleteExcludedPaths()
|
||||
await this.deleteExcludedPaths()
|
||||
await Promise.all([
|
||||
new GradleHomeEntryExtractor(this.gradleUserHome).extract(listener),
|
||||
new ConfigurationCacheEntryExtractor(this.gradleUserHome).extract(listener)
|
||||
@@ -141,13 +144,21 @@ export class GradleStateCache {
|
||||
/**
|
||||
* Delete any file paths that are excluded by the `gradle-home-cache-excludes` parameter.
|
||||
*/
|
||||
private deleteExcludedPaths(): void {
|
||||
const rawPaths: string[] = core.getMultilineInput(EXCLUDE_PATHS_PARAMETER)
|
||||
private async deleteExcludedPaths(): Promise<void> {
|
||||
const rawPaths: string[] = params.getCacheExcludes()
|
||||
rawPaths.push('caches/*/cc-keystore')
|
||||
const resolvedPaths = rawPaths.map(x => path.resolve(this.gradleUserHome, x))
|
||||
|
||||
for (const p of resolvedPaths) {
|
||||
cacheDebug(`Deleting excluded path: ${p}`)
|
||||
tryDelete(p)
|
||||
cacheDebug(`Removing excluded path: ${p}`)
|
||||
const globber = await glob.create(p, {
|
||||
implicitDescendants: false
|
||||
})
|
||||
|
||||
for (const toDelete of await globber.glob()) {
|
||||
cacheDebug(`Removing excluded file: ${toDelete}`)
|
||||
await tryDelete(toDelete)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +168,7 @@ export class GradleStateCache {
|
||||
* but this can be overridden by the `gradle-home-cache-includes` parameter.
|
||||
*/
|
||||
protected getCachePath(): string[] {
|
||||
const rawPaths: string[] = core.getMultilineInput(INCLUDE_PATHS_PARAMETER)
|
||||
const rawPaths: string[] = params.getCacheIncludes()
|
||||
rawPaths.push(META_FILE_DIR)
|
||||
const resolvedPaths = rawPaths.map(x => this.resolveCachePath(x))
|
||||
cacheDebug(`Using cache paths: ${resolvedPaths}`)
|
||||
@@ -172,18 +183,59 @@ export class GradleStateCache {
|
||||
return path.resolve(this.gradleUserHome, rawPath)
|
||||
}
|
||||
|
||||
private initializeGradleUserHome(gradleUserHome: string, initScriptsDir: string): void {
|
||||
const initScriptFilenames = ['build-result-capture.init.gradle', 'build-result-capture-service.plugin.groovy']
|
||||
private initializeGradleUserHome(): void {
|
||||
// Create a directory for storing action metadata
|
||||
const actionCacheDir = path.resolve(this.gradleUserHome, '.gradle-build-action')
|
||||
fs.mkdirSync(actionCacheDir, {recursive: true})
|
||||
|
||||
this.copyInitScripts()
|
||||
|
||||
// Copy the default toolchain definitions to `~/.m2/toolchains.xml`
|
||||
this.registerToolchains()
|
||||
}
|
||||
|
||||
private copyInitScripts(): void {
|
||||
// Copy init scripts from src/resources to Gradle UserHome
|
||||
const initScriptsDir = path.resolve(this.gradleUserHome, 'init.d')
|
||||
fs.mkdirSync(initScriptsDir, {recursive: true})
|
||||
const initScriptFilenames = [
|
||||
'gradle-build-action.build-result-capture.init.gradle',
|
||||
'gradle-build-action.build-result-capture-service.plugin.groovy',
|
||||
'gradle-build-action.github-dependency-graph.init.gradle',
|
||||
'gradle-build-action.github-dependency-graph-gradle-plugin-apply.groovy',
|
||||
'gradle-build-action.inject-gradle-enterprise.init.gradle'
|
||||
]
|
||||
for (const initScriptFilename of initScriptFilenames) {
|
||||
const initScriptContent = this.readInitScriptAsString(initScriptFilename)
|
||||
const initScriptContent = this.readResourceFileAsString('init-scripts', initScriptFilename)
|
||||
const initScriptPath = path.resolve(initScriptsDir, initScriptFilename)
|
||||
fs.writeFileSync(initScriptPath, initScriptContent)
|
||||
}
|
||||
}
|
||||
|
||||
private readInitScriptAsString(resource: string): string {
|
||||
private registerToolchains(): void {
|
||||
const preInstalledToolchains = this.readResourceFileAsString('toolchains.xml')
|
||||
const m2dir = path.resolve(this.userHome, '.m2')
|
||||
const toolchainXmlTarget = path.resolve(m2dir, 'toolchains.xml')
|
||||
if (!fs.existsSync(toolchainXmlTarget)) {
|
||||
// Write a new toolchains.xml file if it doesn't exist
|
||||
fs.mkdirSync(m2dir, {recursive: true})
|
||||
fs.writeFileSync(toolchainXmlTarget, preInstalledToolchains)
|
||||
|
||||
core.info(`Wrote default JDK locations to ${toolchainXmlTarget}`)
|
||||
} else {
|
||||
// Merge into an existing toolchains.xml file
|
||||
const existingToolchainContent = fs.readFileSync(toolchainXmlTarget, 'utf8')
|
||||
const appendedContent = preInstalledToolchains.split('<toolchains>').pop()!
|
||||
const mergedContent = existingToolchainContent.replace('</toolchains>', appendedContent)
|
||||
|
||||
fs.writeFileSync(toolchainXmlTarget, mergedContent)
|
||||
core.info(`Merged default JDK locations into ${toolchainXmlTarget}`)
|
||||
}
|
||||
}
|
||||
|
||||
private readResourceFileAsString(...paths: string[]): string {
|
||||
// Resolving relative to __dirname will allow node to find the resource at runtime
|
||||
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', 'init-scripts', resource)
|
||||
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', ...paths)
|
||||
return fs.readFileSync(absolutePath, 'utf8')
|
||||
}
|
||||
|
||||
|
69
src/cache-cleaner.ts
Normal file
69
src/cache-cleaner.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as glob from '@actions/glob'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export class CacheCleaner {
|
||||
private readonly gradleUserHome: string
|
||||
private readonly tmpDir: string
|
||||
|
||||
constructor(gradleUserHome: string, tmpDir: string) {
|
||||
this.gradleUserHome = gradleUserHome
|
||||
this.tmpDir = tmpDir
|
||||
}
|
||||
|
||||
async prepare(): Promise<void> {
|
||||
// Reset the file-access journal so that files appear not to have been used recently
|
||||
fs.rmSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true, force: true})
|
||||
fs.mkdirSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true})
|
||||
fs.writeFileSync(
|
||||
path.resolve(this.gradleUserHome, 'caches/journal-1/file-access.properties'),
|
||||
'inceptionTimestamp=0'
|
||||
)
|
||||
|
||||
// Set the modification time of all files to the past: this timestamp is used when there is no matching entry in the journal
|
||||
await this.ageAllFiles()
|
||||
|
||||
// Touch all 'gc' files so that cache cleanup won't run immediately.
|
||||
await this.touchAllFiles('gc.properties')
|
||||
}
|
||||
|
||||
async forceCleanup(): Promise<void> {
|
||||
// Age all 'gc' files so that cache cleanup will run immediately.
|
||||
await this.ageAllFiles('gc.properties')
|
||||
|
||||
// Run a dummy Gradle build to trigger cache cleanup
|
||||
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
||||
fs.mkdirSync(cleanupProjectDir, {recursive: true})
|
||||
fs.writeFileSync(
|
||||
path.resolve(cleanupProjectDir, 'settings.gradle'),
|
||||
'rootProject.name = "dummy-cleanup-project"'
|
||||
)
|
||||
fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}')
|
||||
|
||||
const gradleCommand = `gradle -g ${this.gradleUserHome} --no-daemon --build-cache --no-scan --quiet -DGITHUB_DEPENDENCY_GRAPH_ENABLED=false noop`
|
||||
await exec.exec(gradleCommand, [], {
|
||||
cwd: cleanupProjectDir
|
||||
})
|
||||
}
|
||||
|
||||
private async ageAllFiles(fileName = '*'): Promise<void> {
|
||||
core.debug(`Aging all files in Gradle User Home with name ${fileName}`)
|
||||
await this.setUtimes(`${this.gradleUserHome}/**/${fileName}`, new Date(0))
|
||||
}
|
||||
|
||||
private async touchAllFiles(fileName = '*'): Promise<void> {
|
||||
core.debug(`Touching all files in Gradle User Home with name ${fileName}`)
|
||||
await this.setUtimes(`${this.gradleUserHome}/**/${fileName}`, new Date())
|
||||
}
|
||||
|
||||
private async setUtimes(pattern: string, timestamp: Date): Promise<void> {
|
||||
const globber = await glob.create(pattern, {
|
||||
implicitDescendants: false
|
||||
})
|
||||
for await (const file of globber.globGenerator()) {
|
||||
fs.utimesSync(file, timestamp, timestamp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,19 +2,14 @@ import path from 'path'
|
||||
import fs from 'fs'
|
||||
import * as core from '@actions/core'
|
||||
import * as glob from '@actions/glob'
|
||||
import * as semver from 'semver'
|
||||
|
||||
import * as params from './input-params'
|
||||
|
||||
import {META_FILE_DIR} from './cache-base'
|
||||
import {CacheEntryListener, CacheListener} from './cache-reporting'
|
||||
import {
|
||||
cacheDebug,
|
||||
getCacheKeyPrefix,
|
||||
hashFileNames,
|
||||
isCacheDebuggingEnabled,
|
||||
restoreCache,
|
||||
saveCache,
|
||||
tryDelete
|
||||
} from './cache-utils'
|
||||
import {loadBuildResults} from './build-results'
|
||||
import {cacheDebug, getCacheKeyPrefix, hashFileNames, restoreCache, saveCache, tryDelete} from './cache-utils'
|
||||
import {BuildResult, loadBuildResults} from './build-results'
|
||||
|
||||
const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE'
|
||||
|
||||
@@ -52,6 +47,7 @@ class ExtractedCacheEntryDefinition {
|
||||
pattern: string
|
||||
bundle: boolean
|
||||
uniqueFileNames = true
|
||||
notCacheableReason: string | undefined
|
||||
|
||||
constructor(artifactType: string, pattern: string, bundle: boolean) {
|
||||
this.artifactType = artifactType
|
||||
@@ -59,10 +55,24 @@ class ExtractedCacheEntryDefinition {
|
||||
this.bundle = bundle
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the file names matching the cache entry pattern are NOT sufficient to uniquely identify the contents.
|
||||
* If the file names are sufficient, then we use a hash of the file names to identify the entry.
|
||||
* With non-unique-file-names, we hash the file contents to identify the cache entry.
|
||||
*/
|
||||
withNonUniqueFileNames(): ExtractedCacheEntryDefinition {
|
||||
this.uniqueFileNames = false
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that the cache entry, should not be saved for some reason, even though the contents exist.
|
||||
* This is used to prevent configuration-cache entries being cached when they were generated by Gradle < 8.6,
|
||||
*/
|
||||
notCacheableBecause(reason: string): ExtractedCacheEntryDefinition {
|
||||
this.notCacheableReason = reason
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,10 +158,14 @@ abstract class AbstractEntryExtractor {
|
||||
const artifactType = cacheEntryDefinition.artifactType
|
||||
const pattern = cacheEntryDefinition.pattern
|
||||
|
||||
if (cacheEntryDefinition.notCacheableReason) {
|
||||
listener.entry(pattern).markNotSaved(cacheEntryDefinition.notCacheableReason)
|
||||
continue
|
||||
}
|
||||
|
||||
// Find all matching files for this cache entry definition
|
||||
const globber = await glob.create(pattern, {
|
||||
implicitDescendants: false,
|
||||
followSymbolicLinks: false
|
||||
implicitDescendants: false
|
||||
})
|
||||
const matchingFiles = await globber.glob()
|
||||
|
||||
@@ -247,7 +261,7 @@ abstract class AbstractEntryExtractor {
|
||||
|
||||
// Run actions sequentially if debugging is enabled
|
||||
private async awaitForDebugging(p: Promise<ExtractedCacheEntry>): Promise<ExtractedCacheEntry> {
|
||||
if (isCacheDebuggingEnabled()) {
|
||||
if (params.isCacheDebuggingEnabled()) {
|
||||
await p
|
||||
}
|
||||
return p
|
||||
@@ -263,7 +277,7 @@ abstract class AbstractEntryExtractor {
|
||||
}
|
||||
|
||||
const filedata = fs.readFileSync(cacheMetadataFile, 'utf-8')
|
||||
cacheDebug(`Loaded cache metadata: ${filedata}`)
|
||||
cacheDebug(`Loaded cache metadata for ${this.extractorName}: ${filedata}`)
|
||||
const extractedCacheEntryMetadata = JSON.parse(filedata) as ExtractedCacheEntryMetadata
|
||||
return extractedCacheEntryMetadata.entries
|
||||
}
|
||||
@@ -271,12 +285,12 @@ abstract class AbstractEntryExtractor {
|
||||
/**
|
||||
* Saves information about the extracted cache entries into the 'cache-metadata.json' file.
|
||||
*/
|
||||
private saveMetadataForCacheResults(results: ExtractedCacheEntry[]): void {
|
||||
protected saveMetadataForCacheResults(results: ExtractedCacheEntry[]): void {
|
||||
const extractedCacheEntryMetadata = new ExtractedCacheEntryMetadata()
|
||||
extractedCacheEntryMetadata.entries = results.filter(x => x.cacheKey !== undefined)
|
||||
|
||||
const filedata = JSON.stringify(extractedCacheEntryMetadata)
|
||||
cacheDebug(`Saving cache metadata: ${filedata}`)
|
||||
cacheDebug(`Saving cache metadata for ${this.extractorName}: ${filedata}`)
|
||||
|
||||
fs.writeFileSync(this.getCacheMetadataFile(), filedata, 'utf-8')
|
||||
}
|
||||
@@ -308,8 +322,7 @@ export class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
||||
private async deleteWrapperZips(): Promise<void> {
|
||||
const wrapperZips = path.resolve(this.gradleUserHome, 'wrapper/dists/*/*/*.zip')
|
||||
const globber = await glob.create(wrapperZips, {
|
||||
implicitDescendants: false,
|
||||
followSymbolicLinks: false
|
||||
implicitDescendants: false
|
||||
})
|
||||
|
||||
for (const wrapperZip of await globber.glob()) {
|
||||
@@ -340,8 +353,8 @@ export class GradleHomeEntryExtractor extends AbstractEntryExtractor {
|
||||
|
||||
return [
|
||||
entryDefinition('generated-gradle-jars', ['caches/*/generated-gradle-jars/*.jar'], false),
|
||||
entryDefinition('wrapper-zips', ['wrapper/dists/*/*/'], false), // Entire wrapper directory cached together
|
||||
entryDefinition('java-toolchains', ['jdks/*.zip', 'jdks/*.tar.gz'], false),
|
||||
entryDefinition('wrapper-zips', ['wrapper/dists/*/*/'], false), // Each wrapper directory cached separately
|
||||
entryDefinition('java-toolchains', ['jdks/*/'], false), // Each extracted JDK cached separately
|
||||
entryDefinition('dependencies', ['caches/modules-*/files-*/*/*/*/*'], true),
|
||||
entryDefinition('instrumented-jars', ['caches/jars-*/*'], true),
|
||||
entryDefinition('kotlin-dsl', ['caches/*/kotlin-dsl/*/*'], true)
|
||||
@@ -359,37 +372,96 @@ export class ConfigurationCacheEntryExtractor extends AbstractEntryExtractor {
|
||||
* entry is not reusable.
|
||||
*/
|
||||
async restore(listener: CacheListener): Promise<void> {
|
||||
if (listener.fullyRestored) {
|
||||
return super.restore(listener)
|
||||
if (!listener.fullyRestored) {
|
||||
this.markNotRestored(listener, 'Gradle User Home was not fully restored')
|
||||
return
|
||||
}
|
||||
|
||||
core.info('Not restoring configuration-cache state, as Gradle User Home was not fully restored')
|
||||
for (const cacheEntry of this.loadExtractedCacheEntries()) {
|
||||
listener.entry(cacheEntry.pattern).markRequested('NOT_RESTORED')
|
||||
if (!params.getCacheEncryptionKey()) {
|
||||
this.markNotRestored(listener, 'Encryption Key was not provided')
|
||||
return
|
||||
}
|
||||
|
||||
return await super.restore(listener)
|
||||
}
|
||||
|
||||
private markNotRestored(listener: CacheListener, reason: string): void {
|
||||
const cacheEntries = this.loadExtractedCacheEntries()
|
||||
if (cacheEntries.length > 0) {
|
||||
core.info(`Not restoring configuration-cache state, as ${reason}`)
|
||||
for (const cacheEntry of cacheEntries) {
|
||||
listener.entry(cacheEntry.pattern).markNotRestored(reason)
|
||||
}
|
||||
|
||||
// Update the results file based on no entries restored
|
||||
this.saveMetadataForCacheResults([])
|
||||
}
|
||||
}
|
||||
|
||||
async extract(listener: CacheListener): Promise<void> {
|
||||
if (!params.getCacheEncryptionKey()) {
|
||||
const cacheEntryDefinitions = this.getExtractedCacheEntryDefinitions()
|
||||
if (cacheEntryDefinitions.length > 0) {
|
||||
core.info('Not saving configuration-cache state, as no encryption key was provided')
|
||||
for (const cacheEntry of cacheEntryDefinitions) {
|
||||
listener.entry(cacheEntry.pattern).markNotSaved('No encryption key provided')
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
await super.extract(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract cache entries for the configuration cache in each project.
|
||||
*/
|
||||
protected getExtractedCacheEntryDefinitions(): ExtractedCacheEntryDefinition[] {
|
||||
return this.getProjectRoots().map(projectRoot => {
|
||||
const configCachePath = path.resolve(projectRoot, '.gradle/configuration-cache')
|
||||
return new ExtractedCacheEntryDefinition(
|
||||
// Group BuildResult by existing configCacheDir
|
||||
const groupedResults = this.getConfigCacheDirectoriesWithAssociatedBuildResults()
|
||||
|
||||
return Object.entries(groupedResults).map(([configCachePath, pathResults]) => {
|
||||
// Create a entry definition for each unique configuration cache directory
|
||||
const definition = new ExtractedCacheEntryDefinition(
|
||||
'configuration-cache',
|
||||
configCachePath,
|
||||
true
|
||||
).withNonUniqueFileNames()
|
||||
|
||||
// If any associated build result used Gradle < 8.6, then mark it as not cacheable
|
||||
if (
|
||||
pathResults.find(result => {
|
||||
const gradleVersion = semver.coerce(result.gradleVersion)
|
||||
return gradleVersion && semver.lt(gradleVersion, '8.6.0')
|
||||
})
|
||||
) {
|
||||
core.info(
|
||||
`Not saving config-cache data for ${configCachePath}. Configuration cache data is only saved for Gradle 8.6+`
|
||||
)
|
||||
definition.notCacheableBecause('Configuration cache data only saved for Gradle 8.6+')
|
||||
}
|
||||
return definition
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* For every Gradle invocation, we record the project root directory. This method returns the entire
|
||||
* set of project roots, to allow saving of configuration-cache entries for each.
|
||||
*/
|
||||
private getProjectRoots(): string[] {
|
||||
const buildResults = loadBuildResults()
|
||||
const projectRootDirs = buildResults.map(x => x.rootProjectDir)
|
||||
return [...new Set(projectRootDirs)] // Remove duplicates
|
||||
private getConfigCacheDirectoriesWithAssociatedBuildResults(): Record<string, BuildResult[]> {
|
||||
return loadBuildResults().reduce(
|
||||
(acc, buildResult) => {
|
||||
// For each build result, find the config-cache dir
|
||||
const configCachePath = path.resolve(buildResult.rootProjectDir, '.gradle/configuration-cache')
|
||||
// Ignore case where config-cache dir doesn't exist
|
||||
if (!fs.existsSync(configCachePath)) {
|
||||
return acc
|
||||
}
|
||||
|
||||
// Group by unique config cache directories and collect associated build results
|
||||
if (!acc[configCachePath]) {
|
||||
acc[configCachePath] = []
|
||||
}
|
||||
acc[configCachePath].push(buildResult)
|
||||
return acc
|
||||
},
|
||||
{} as Record<string, BuildResult[]>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as cache from '@actions/cache'
|
||||
|
||||
/**
|
||||
@@ -10,6 +9,7 @@ export class CacheListener {
|
||||
cacheReadOnly = false
|
||||
cacheWriteOnly = false
|
||||
cacheDisabled = false
|
||||
cacheDisabledReason = 'disabled'
|
||||
|
||||
get fullyRestored(): boolean {
|
||||
return this.cacheEntries.every(x => !x.wasRequestedButNotRestored())
|
||||
@@ -17,7 +17,7 @@ export class CacheListener {
|
||||
|
||||
get cacheStatus(): string {
|
||||
if (!cache.isFeatureAvailable()) return 'not available'
|
||||
if (this.cacheDisabled) return 'disabled'
|
||||
if (this.cacheDisabled) return this.cacheDisabledReason
|
||||
if (this.cacheWriteOnly) return 'write-only'
|
||||
if (this.cacheReadOnly) return 'read-only'
|
||||
return 'enabled'
|
||||
@@ -111,47 +111,36 @@ export class CacheEntryListener {
|
||||
}
|
||||
}
|
||||
|
||||
export function writeCachingReport(listener: CacheListener): void {
|
||||
export function generateCachingReport(listener: CacheListener): string {
|
||||
const entries = listener.cacheEntries
|
||||
|
||||
core.summary.addRaw(
|
||||
`\n<details><summary><h4>Caching for gradle-build-action was ${listener.cacheStatus} - expand for details</h4></summary>\n`
|
||||
)
|
||||
return `
|
||||
<details>
|
||||
<summary><h4>Caching for gradle-build-action was ${listener.cacheStatus} - expand for details</h4></summary>
|
||||
${renderEntryTable(entries)}
|
||||
|
||||
core.summary.addTable([
|
||||
[
|
||||
{data: '', header: true},
|
||||
{data: 'Count', header: true},
|
||||
{data: 'Total Size (Mb)', header: true}
|
||||
],
|
||||
['Entries Restored', `${getCount(entries, e => e.restoredSize)}`, `${getSize(entries, e => e.restoredSize)}`],
|
||||
['Entries Saved', `${getCount(entries, e => e.savedSize)}`, `${getSize(entries, e => e.savedSize)}`]
|
||||
])
|
||||
|
||||
core.summary.addHeading('Cache Entry Details', 5)
|
||||
|
||||
const entryDetails = renderEntryDetails(listener)
|
||||
core.summary.addRaw(`<pre>
|
||||
${entryDetails}
|
||||
<h5>Cache Entry Details</h5>
|
||||
<pre>
|
||||
${renderEntryDetails(listener)}
|
||||
</pre>
|
||||
</details>
|
||||
`)
|
||||
`
|
||||
}
|
||||
|
||||
export function logCachingReport(listener: CacheListener): void {
|
||||
const entries = listener.cacheEntries
|
||||
|
||||
core.startGroup(`Caching for gradle-build-action was ${listener.cacheStatus} - expand for details`)
|
||||
|
||||
core.info(
|
||||
`Entries Restored: ${getCount(entries, e => e.restoredSize)} (${getSize(entries, e => e.restoredSize)} Mb)`
|
||||
)
|
||||
core.info(`Entries Saved : ${getCount(entries, e => e.savedSize)} (${getSize(entries, e => e.savedSize)} Mb)`)
|
||||
|
||||
core.info(`Cache Entry Details`)
|
||||
core.info(renderEntryDetails(listener))
|
||||
|
||||
core.endGroup()
|
||||
function renderEntryTable(entries: CacheEntryListener[]): string {
|
||||
return `
|
||||
<table>
|
||||
<tr><td></td><th>Count</th><th>Total Size (Mb)</th></tr>
|
||||
<tr><td>Entries Restored</td>
|
||||
<td>${getCount(entries, e => e.restoredSize)}</td>
|
||||
<td>${getSize(entries, e => e.restoredSize)}</td>
|
||||
</tr>
|
||||
<tr><td>Entries Saved</td>
|
||||
<td>${getCount(entries, e => e.savedSize)}</td>
|
||||
<td>${getSize(entries, e => e.savedSize)}</td>
|
||||
</tr>
|
||||
</table>
|
||||
`
|
||||
}
|
||||
|
||||
function renderEntryDetails(listener: CacheListener): string {
|
||||
@@ -197,6 +186,9 @@ function getSavedMessage(entry: CacheEntryListener, cacheReadOnly: boolean): str
|
||||
if (cacheReadOnly) {
|
||||
return '(Entry not saved: cache is read-only)'
|
||||
}
|
||||
if (entry.notRestored) {
|
||||
return '(Entry not saved: not restored)'
|
||||
}
|
||||
return '(Entry not saved: reason unknown)'
|
||||
}
|
||||
if (entry.savedSize === 0) {
|
||||
|
@@ -7,17 +7,11 @@ import * as crypto from 'crypto'
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
|
||||
import * as params from './input-params'
|
||||
|
||||
import {CacheEntryListener} from './cache-reporting'
|
||||
|
||||
const CACHE_PROTOCOL_VERSION = 'v6-'
|
||||
|
||||
const JOB_CONTEXT_PARAMETER = 'workflow-job-context'
|
||||
const CACHE_DISABLED_PARAMETER = 'cache-disabled'
|
||||
const CACHE_READONLY_PARAMETER = 'cache-read-only'
|
||||
const CACHE_WRITEONLY_PARAMETER = 'cache-write-only'
|
||||
const CACHE_TIMEOUT_PARAMETER = 'cache-read-timeout'
|
||||
const STRICT_CACHE_MATCH_PARAMETER = 'gradle-home-cache-strict-match'
|
||||
const CACHE_DEBUG_VAR = 'GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED'
|
||||
const CACHE_PROTOCOL_VERSION = 'v9-'
|
||||
|
||||
const CACHE_KEY_PREFIX_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX'
|
||||
const CACHE_KEY_OS_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_ENVIRONMENT'
|
||||
@@ -25,27 +19,34 @@ const CACHE_KEY_JOB_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB'
|
||||
const CACHE_KEY_JOB_INSTANCE_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB_INSTANCE'
|
||||
const CACHE_KEY_JOB_EXECUTION_VAR = 'GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION'
|
||||
|
||||
const SEGMENT_DOWNLOAD_TIMEOUT_VAR = 'SEGMENT_DOWNLOAD_TIMEOUT_MINS'
|
||||
const SEGMENT_DOWNLOAD_TIMEOUT_DEFAULT = 10 * 60 * 1000 // 10 minutes
|
||||
|
||||
export function isCacheDisabled(): boolean {
|
||||
if (!cache.isFeatureAvailable()) {
|
||||
return true
|
||||
}
|
||||
return core.getBooleanInput(CACHE_DISABLED_PARAMETER)
|
||||
return params.isCacheDisabled()
|
||||
}
|
||||
|
||||
export function isCacheReadOnly(): boolean {
|
||||
return !isCacheWriteOnly() && core.getBooleanInput(CACHE_READONLY_PARAMETER)
|
||||
return !isCacheWriteOnly() && params.isCacheReadOnly()
|
||||
}
|
||||
|
||||
export function isCacheWriteOnly(): boolean {
|
||||
return core.getBooleanInput(CACHE_WRITEONLY_PARAMETER)
|
||||
return params.isCacheWriteOnly()
|
||||
}
|
||||
|
||||
export function isCacheOverwriteExisting(): boolean {
|
||||
return params.isCacheOverwriteExisting()
|
||||
}
|
||||
|
||||
export function isCacheDebuggingEnabled(): boolean {
|
||||
return process.env[CACHE_DEBUG_VAR] ? true : false
|
||||
return params.isCacheDebuggingEnabled()
|
||||
}
|
||||
|
||||
function getCacheReadTimeoutMs(): number {
|
||||
return parseInt(core.getInput(CACHE_TIMEOUT_PARAMETER)) * 1000
|
||||
export function isCacheCleanupEnabled(): boolean {
|
||||
return params.isCacheCleanupEnabled()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +70,7 @@ export class CacheKey {
|
||||
* - The cache protocol version
|
||||
* - The name of the cache
|
||||
* - The runner operating system
|
||||
* - The name of the Job being executed
|
||||
* - The name of the workflow and Job being executed
|
||||
* - The matrix values for the Job being executed (job context)
|
||||
* - The SHA of the commit being executed
|
||||
*
|
||||
@@ -85,16 +86,16 @@ export function generateCacheKey(cacheName: string): CacheKey {
|
||||
// At the most general level, share caches for all executions on the same OS
|
||||
const cacheKeyForEnvironment = `${cacheKeyBase}|${getCacheKeyEnvironment()}`
|
||||
|
||||
// Prefer caches that run this job
|
||||
// Then prefer caches that run job with the same ID
|
||||
const cacheKeyForJob = `${cacheKeyForEnvironment}|${getCacheKeyJob()}`
|
||||
|
||||
// Prefer (even more) jobs that run this job with the same context (matrix)
|
||||
// Prefer (even more) jobs that run this job in the same workflow with the same context (matrix)
|
||||
const cacheKeyForJobContext = `${cacheKeyForJob}[${getCacheKeyJobInstance()}]`
|
||||
|
||||
// Exact match on Git SHA
|
||||
const cacheKey = `${cacheKeyForJobContext}-${getCacheKeyJobExecution()}`
|
||||
|
||||
if (core.getBooleanInput(STRICT_CACHE_MATCH_PARAMETER)) {
|
||||
if (params.isCacheStrictMatch()) {
|
||||
return new CacheKey(cacheKey, [cacheKeyForJobContext])
|
||||
}
|
||||
|
||||
@@ -112,7 +113,6 @@ function getCacheKeyEnvironment(): string {
|
||||
}
|
||||
|
||||
function getCacheKeyJob(): string {
|
||||
// Prefix can be used to force change all cache keys (defaults to cache protocol version)
|
||||
return process.env[CACHE_KEY_JOB_VAR] || github.context.job
|
||||
}
|
||||
|
||||
@@ -122,10 +122,11 @@ function getCacheKeyJobInstance(): string {
|
||||
return override
|
||||
}
|
||||
|
||||
// By default, we hash the full `matrix` data for the run, to uniquely identify this job invocation
|
||||
// By default, we hash the workflow name and the full `matrix` data for the run, to uniquely identify this job invocation
|
||||
// The only way we can obtain the `matrix` data is via the `workflow-job-context` parameter in action.yml.
|
||||
const workflowJobContext = core.getInput(JOB_CONTEXT_PARAMETER)
|
||||
return hashStrings([workflowJobContext])
|
||||
const workflowName = github.context.workflow
|
||||
const workflowJobContext = params.getJobMatrix()
|
||||
return hashStrings([workflowName, workflowJobContext])
|
||||
}
|
||||
|
||||
function getCacheKeyJobExecution(): string {
|
||||
@@ -153,9 +154,11 @@ export async function restoreCache(
|
||||
): Promise<cache.CacheEntry | undefined> {
|
||||
listener.markRequested(cacheKey, cacheRestoreKeys)
|
||||
try {
|
||||
const restoredEntry = await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys, {
|
||||
segmentTimeoutInMs: getCacheReadTimeoutMs()
|
||||
})
|
||||
// Only override the read timeout if the SEGMENT_DOWNLOAD_TIMEOUT_MINS env var has NOT been set
|
||||
const cacheRestoreOptions = process.env[SEGMENT_DOWNLOAD_TIMEOUT_VAR]
|
||||
? {}
|
||||
: {segmentTimeoutInMs: SEGMENT_DOWNLOAD_TIMEOUT_DEFAULT}
|
||||
const restoredEntry = await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys, cacheRestoreOptions)
|
||||
if (restoredEntry !== undefined) {
|
||||
listener.markRestored(restoredEntry.key, restoredEntry.size)
|
||||
}
|
||||
@@ -218,7 +221,7 @@ export async function tryDelete(file: string): Promise<void> {
|
||||
try {
|
||||
const stat = fs.lstatSync(file)
|
||||
if (stat.isDirectory()) {
|
||||
fs.rmdirSync(file, {recursive: true})
|
||||
fs.rmSync(file, {recursive: true})
|
||||
} else {
|
||||
fs.unlinkSync(file)
|
||||
}
|
||||
|
@@ -1,12 +1,19 @@
|
||||
import * as core from '@actions/core'
|
||||
import {isCacheDisabled, isCacheReadOnly, isCacheWriteOnly} from './cache-utils'
|
||||
import {
|
||||
isCacheCleanupEnabled,
|
||||
isCacheDisabled,
|
||||
isCacheReadOnly,
|
||||
isCacheWriteOnly,
|
||||
isCacheOverwriteExisting
|
||||
} from './cache-utils'
|
||||
import {CacheListener} from './cache-reporting'
|
||||
import {DaemonController} from './daemon-controller'
|
||||
import {GradleStateCache} from './cache-base'
|
||||
import {CacheCleaner} from './cache-cleaner'
|
||||
|
||||
const CACHE_RESTORED_VAR = 'GRADLE_BUILD_ACTION_CACHE_RESTORED'
|
||||
|
||||
export async function restore(gradleUserHome: string, cacheListener: CacheListener): Promise<void> {
|
||||
export async function restore(userHome: string, gradleUserHome: string, cacheListener: CacheListener): Promise<void> {
|
||||
// Bypass restore cache on all but first action step in workflow.
|
||||
if (process.env[CACHE_RESTORED_VAR]) {
|
||||
core.info('Cache only restored on first action step.')
|
||||
@@ -14,7 +21,7 @@ export async function restore(gradleUserHome: string, cacheListener: CacheListen
|
||||
}
|
||||
core.exportVariable(CACHE_RESTORED_VAR, true)
|
||||
|
||||
const gradleStateCache = new GradleStateCache(gradleUserHome)
|
||||
const gradleStateCache = new GradleStateCache(userHome, gradleUserHome)
|
||||
|
||||
if (isCacheDisabled()) {
|
||||
core.info('Cache is disabled: will not restore state from previous builds.')
|
||||
@@ -25,10 +32,15 @@ export async function restore(gradleUserHome: string, cacheListener: CacheListen
|
||||
}
|
||||
|
||||
if (gradleStateCache.cacheOutputExists()) {
|
||||
core.info('Gradle User Home already exists: will not restore from cache.')
|
||||
// Initialize pre-existing Gradle User Home.
|
||||
gradleStateCache.init()
|
||||
return
|
||||
if (!isCacheOverwriteExisting()) {
|
||||
core.info('Gradle User Home already exists: will not restore from cache.')
|
||||
// Initialize pre-existing Gradle User Home.
|
||||
gradleStateCache.init()
|
||||
cacheListener.cacheDisabled = true
|
||||
cacheListener.cacheDisabledReason = 'disabled due to pre-existing Gradle User Home'
|
||||
return
|
||||
}
|
||||
core.info('Gradle User Home already exists: will overwrite with cached contents.')
|
||||
}
|
||||
|
||||
gradleStateCache.init()
|
||||
@@ -44,9 +56,16 @@ export async function restore(gradleUserHome: string, cacheListener: CacheListen
|
||||
await core.group('Restore Gradle state from cache', async () => {
|
||||
await gradleStateCache.restore(cacheListener)
|
||||
})
|
||||
|
||||
if (isCacheCleanupEnabled() && !isCacheReadOnly()) {
|
||||
core.info('Preparing cache for cleanup.')
|
||||
const cacheCleaner = new CacheCleaner(gradleUserHome, process.env['RUNNER_TEMP']!)
|
||||
await cacheCleaner.prepare()
|
||||
}
|
||||
}
|
||||
|
||||
export async function save(
|
||||
userHome: string,
|
||||
gradleUserHome: string,
|
||||
cacheListener: CacheListener,
|
||||
daemonController: DaemonController
|
||||
@@ -69,7 +88,17 @@ export async function save(
|
||||
|
||||
await daemonController.stopAllDaemons()
|
||||
|
||||
if (isCacheCleanupEnabled()) {
|
||||
core.info('Forcing cache cleanup.')
|
||||
const cacheCleaner = new CacheCleaner(gradleUserHome, process.env['RUNNER_TEMP']!)
|
||||
try {
|
||||
await cacheCleaner.forceCleanup()
|
||||
} catch (e) {
|
||||
core.warning(`Cache cleanup failed. Will continue. ${String(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
await core.group('Caching Gradle state', async () => {
|
||||
return new GradleStateCache(gradleUserHome).save(cacheListener)
|
||||
return new GradleStateCache(userHome, gradleUserHome).save(cacheListener)
|
||||
})
|
||||
}
|
||||
|
219
src/dependency-graph.ts
Normal file
219
src/dependency-graph.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import * as glob from '@actions/glob'
|
||||
import {DefaultArtifactClient} from '@actions/artifact'
|
||||
import {GitHub} from '@actions/github/lib/utils'
|
||||
import {RequestError} from '@octokit/request-error'
|
||||
import type {PullRequestEvent} from '@octokit/webhooks-types'
|
||||
|
||||
import * as path from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
import * as layout from './repository-layout'
|
||||
import {DependencyGraphOption, getJobMatrix, getArtifactRetentionDays} from './input-params'
|
||||
|
||||
const DEPENDENCY_GRAPH_PREFIX = 'dependency-graph_'
|
||||
|
||||
export async function setup(option: DependencyGraphOption): Promise<void> {
|
||||
if (option === DependencyGraphOption.Disabled) {
|
||||
return
|
||||
}
|
||||
// Download and submit early, for compatability with dependency review.
|
||||
if (option === DependencyGraphOption.DownloadAndSubmit) {
|
||||
await downloadAndSubmitDependencyGraphs()
|
||||
return
|
||||
}
|
||||
|
||||
core.info('Enabling dependency graph generation')
|
||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED', 'true')
|
||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR', getJobCorrelator())
|
||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_ID', github.context.runId)
|
||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_REF', github.context.ref)
|
||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_SHA', getShaFromContext())
|
||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_WORKSPACE', layout.workspaceDirectory())
|
||||
core.exportVariable(
|
||||
'DEPENDENCY_GRAPH_REPORT_DIR',
|
||||
path.resolve(layout.workspaceDirectory(), 'dependency-graph-reports')
|
||||
)
|
||||
}
|
||||
|
||||
export async function complete(option: DependencyGraphOption): Promise<void> {
|
||||
try {
|
||||
switch (option) {
|
||||
case DependencyGraphOption.Disabled:
|
||||
case DependencyGraphOption.Generate: // Performed via init-script: nothing to do here
|
||||
case DependencyGraphOption.DownloadAndSubmit: // Performed in setup
|
||||
return
|
||||
case DependencyGraphOption.GenerateAndSubmit:
|
||||
await submitDependencyGraphs(await findGeneratedDependencyGraphFiles())
|
||||
return
|
||||
case DependencyGraphOption.GenerateAndUpload:
|
||||
await uploadDependencyGraphs(await findGeneratedDependencyGraphFiles())
|
||||
}
|
||||
} catch (e) {
|
||||
core.warning(`Failed to ${option} dependency graph. Will continue. ${String(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function findGeneratedDependencyGraphFiles(): Promise<string[]> {
|
||||
const workspaceDirectory = layout.workspaceDirectory()
|
||||
return await findDependencyGraphFiles(workspaceDirectory)
|
||||
}
|
||||
|
||||
async function uploadDependencyGraphs(dependencyGraphFiles: string[]): Promise<void> {
|
||||
const workspaceDirectory = layout.workspaceDirectory()
|
||||
|
||||
const artifactClient = new DefaultArtifactClient()
|
||||
for (const dependencyGraphFile of dependencyGraphFiles) {
|
||||
const relativePath = getRelativePathFromWorkspace(dependencyGraphFile)
|
||||
core.info(`Uploading dependency graph file: ${relativePath}`)
|
||||
const artifactName = `${DEPENDENCY_GRAPH_PREFIX}${path.basename(dependencyGraphFile)}`
|
||||
await artifactClient.uploadArtifact(artifactName, [dependencyGraphFile], workspaceDirectory, {
|
||||
retentionDays: getArtifactRetentionDays()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadAndSubmitDependencyGraphs(): Promise<void> {
|
||||
try {
|
||||
await submitDependencyGraphs(await downloadDependencyGraphs())
|
||||
} catch (e) {
|
||||
core.warning(`Download and submit dependency graph failed. Will continue. ${String(e)}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<void> {
|
||||
for (const jsonFile of dependencyGraphFiles) {
|
||||
try {
|
||||
await submitDependencyGraphFile(jsonFile)
|
||||
} catch (error) {
|
||||
if (error instanceof RequestError) {
|
||||
core.warning(buildWarningMessage(jsonFile, error))
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildWarningMessage(jsonFile: string, error: RequestError): string {
|
||||
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
||||
const mainWarning = `Failed to submit dependency graph ${relativeJsonFile}.\n${String(error)}`
|
||||
if (error.message === 'Resource not accessible by integration') {
|
||||
return `${mainWarning}
|
||||
Please ensure that the 'contents: write' permission is available for the workflow job.
|
||||
Note that this permission is never available for a 'pull_request' trigger from a repository fork.
|
||||
`
|
||||
}
|
||||
return mainWarning
|
||||
}
|
||||
|
||||
async function submitDependencyGraphFile(jsonFile: string): Promise<void> {
|
||||
const octokit = getOctokit()
|
||||
const jsonContent = fs.readFileSync(jsonFile, 'utf8')
|
||||
|
||||
const jsonObject = JSON.parse(jsonContent)
|
||||
jsonObject.owner = github.context.repo.owner
|
||||
jsonObject.repo = github.context.repo.repo
|
||||
const response = await octokit.request('POST /repos/{owner}/{repo}/dependency-graph/snapshots', jsonObject)
|
||||
|
||||
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
||||
core.notice(`Submitted ${relativeJsonFile}: ${response.data.message}`)
|
||||
}
|
||||
|
||||
async function downloadDependencyGraphs(): Promise<string[]> {
|
||||
const workspaceDirectory = layout.workspaceDirectory()
|
||||
|
||||
const findBy = github.context.payload.workflow_run
|
||||
? {
|
||||
token: getGithubToken(),
|
||||
workflowRunId: github.context.payload.workflow_run.id,
|
||||
repositoryName: github.context.repo.repo,
|
||||
repositoryOwner: github.context.repo.owner
|
||||
}
|
||||
: undefined
|
||||
|
||||
const artifactClient = new DefaultArtifactClient()
|
||||
const downloadPath = path.resolve(workspaceDirectory, 'dependency-graph')
|
||||
|
||||
const dependencyGraphArtifacts = (
|
||||
await artifactClient.listArtifacts({
|
||||
latest: true,
|
||||
findBy
|
||||
})
|
||||
).artifacts.filter(candidate => candidate.name.startsWith(DEPENDENCY_GRAPH_PREFIX))
|
||||
|
||||
for (const artifact of dependencyGraphArtifacts) {
|
||||
const downloadedArtifact = await artifactClient.downloadArtifact(artifact.id, {
|
||||
path: downloadPath,
|
||||
findBy
|
||||
})
|
||||
core.info(`Downloading dependency-graph artifact ${artifact.name} to ${downloadedArtifact.downloadPath}`)
|
||||
}
|
||||
|
||||
return findDependencyGraphFiles(downloadPath)
|
||||
}
|
||||
|
||||
async function findDependencyGraphFiles(dir: string): Promise<string[]> {
|
||||
const globber = await glob.create(`${dir}/dependency-graph-reports/*.json`)
|
||||
const graphFiles = globber.glob()
|
||||
return graphFiles
|
||||
}
|
||||
|
||||
function getOctokit(): InstanceType<typeof GitHub> {
|
||||
return github.getOctokit(getGithubToken())
|
||||
}
|
||||
|
||||
function getGithubToken(): string {
|
||||
return core.getInput('github-token', {required: true})
|
||||
}
|
||||
|
||||
function getRelativePathFromWorkspace(file: string): string {
|
||||
const workspaceDirectory = layout.workspaceDirectory()
|
||||
return path.relative(workspaceDirectory, file)
|
||||
}
|
||||
|
||||
function getShaFromContext(): string {
|
||||
const context = github.context
|
||||
const pullRequestEvents = [
|
||||
'pull_request',
|
||||
'pull_request_comment',
|
||||
'pull_request_review',
|
||||
'pull_request_review_comment'
|
||||
// Note that pull_request_target is omitted here.
|
||||
// That event runs in the context of the base commit of the PR,
|
||||
// so the snapshot should not be associated with the head commit.
|
||||
]
|
||||
if (pullRequestEvents.includes(context.eventName)) {
|
||||
const pr = (context.payload as PullRequestEvent).pull_request
|
||||
return pr.head.sha
|
||||
} else {
|
||||
return context.sha
|
||||
}
|
||||
}
|
||||
|
||||
function getJobCorrelator(): string {
|
||||
return constructJobCorrelator(github.context.workflow, github.context.job, getJobMatrix())
|
||||
}
|
||||
|
||||
export function constructJobCorrelator(workflow: string, jobId: string, matrixJson: string): string {
|
||||
const matrixString = describeMatrix(matrixJson)
|
||||
const label = matrixString ? `${workflow}-${jobId}-${matrixString}` : `${workflow}-${jobId}`
|
||||
return sanitize(label)
|
||||
}
|
||||
|
||||
function describeMatrix(matrixJson: string): string {
|
||||
core.debug(`Got matrix json: ${matrixJson}`)
|
||||
const matrix = JSON.parse(matrixJson)
|
||||
if (matrix) {
|
||||
return Object.values(matrix).join('-')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function sanitize(value: string): string {
|
||||
return value
|
||||
.replace(/[^a-zA-Z0-9_-\s]/g, '')
|
||||
.replace(/\s+/g, '_')
|
||||
.toLowerCase()
|
||||
}
|
@@ -1,12 +1,11 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import fs from 'fs'
|
||||
import * as gradlew from './gradlew'
|
||||
|
||||
export async function executeGradleBuild(executable: string | undefined, root: string, args: string[]): Promise<void> {
|
||||
// Use the provided executable, or look for a Gradle wrapper script to run
|
||||
const toExecute = executable ?? gradlew.locateGradleWrapperScript(root)
|
||||
verifyIsExecutableScript(toExecute)
|
||||
const toExecute = executable ?? gradlew.gradleWrapperScript(root)
|
||||
|
||||
const status: number = await exec.exec(toExecute, args, {
|
||||
cwd: root,
|
||||
ignoreReturnCode: true
|
||||
@@ -16,11 +15,3 @@ export async function executeGradleBuild(executable: string | undefined, root: s
|
||||
core.setFailed(`Gradle build failed: see console output for details`)
|
||||
}
|
||||
}
|
||||
|
||||
function verifyIsExecutableScript(toExecute: string): void {
|
||||
try {
|
||||
fs.accessSync(toExecute, fs.constants.X_OK)
|
||||
} catch (err) {
|
||||
throw new Error(`Gradle script '${toExecute}' is not executable.`)
|
||||
}
|
||||
}
|
||||
|
@@ -4,23 +4,39 @@ import fs from 'fs'
|
||||
const IS_WINDOWS = process.platform === 'win32'
|
||||
|
||||
export function wrapperScriptFilename(): string {
|
||||
return IS_WINDOWS ? 'gradlew.bat' : 'gradlew'
|
||||
return IS_WINDOWS ? './gradlew.bat' : './gradlew'
|
||||
}
|
||||
|
||||
export function installScriptFilename(): string {
|
||||
return IS_WINDOWS ? 'gradle.bat' : 'gradle'
|
||||
}
|
||||
|
||||
export function locateGradleWrapperScript(buildRootDirectory: string): string {
|
||||
export function gradleWrapperScript(buildRootDirectory: string): string {
|
||||
validateGradleWrapper(buildRootDirectory)
|
||||
return path.resolve(buildRootDirectory, wrapperScriptFilename())
|
||||
return wrapperScriptFilename()
|
||||
}
|
||||
|
||||
function validateGradleWrapper(buildRootDirectory: string): void {
|
||||
const wrapperScript = path.resolve(buildRootDirectory, wrapperScriptFilename())
|
||||
verifyExists(wrapperScript, 'Gradle Wrapper script')
|
||||
verifyIsExecutableScript(wrapperScript)
|
||||
|
||||
const wrapperProperties = path.resolve(buildRootDirectory, 'gradle/wrapper/gradle-wrapper.properties')
|
||||
if (!fs.existsSync(wrapperProperties)) {
|
||||
verifyExists(wrapperProperties, 'Gradle wrapper properties file')
|
||||
}
|
||||
|
||||
function verifyExists(file: string, description: string): void {
|
||||
if (!fs.existsSync(file)) {
|
||||
throw new Error(
|
||||
`Cannot locate a Gradle wrapper properties file at '${wrapperProperties}'. Specify 'gradle-version' or 'gradle-executable' for projects without Gradle wrapper configured.`
|
||||
`Cannot locate ${description} at '${file}'. Specify 'gradle-version' or 'gradle-executable' for projects without Gradle wrapper configured.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function verifyIsExecutableScript(toExecute: string): void {
|
||||
try {
|
||||
fs.accessSync(toExecute, fs.constants.X_OK)
|
||||
} catch (err) {
|
||||
throw new Error(`Gradle script '${toExecute}' is not executable.`)
|
||||
}
|
||||
}
|
||||
|
156
src/input-params.ts
Normal file
156
src/input-params.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import * as core from '@actions/core'
|
||||
import {parseArgsStringToArgv} from 'string-argv'
|
||||
|
||||
export function isCacheDisabled(): boolean {
|
||||
return getBooleanInput('cache-disabled')
|
||||
}
|
||||
|
||||
export function isCacheReadOnly(): boolean {
|
||||
return getBooleanInput('cache-read-only')
|
||||
}
|
||||
|
||||
export function isCacheWriteOnly(): boolean {
|
||||
return getBooleanInput('cache-write-only')
|
||||
}
|
||||
|
||||
export function isCacheOverwriteExisting(): boolean {
|
||||
return getBooleanInput('cache-overwrite-existing')
|
||||
}
|
||||
|
||||
export function isCacheStrictMatch(): boolean {
|
||||
return getBooleanInput('gradle-home-cache-strict-match')
|
||||
}
|
||||
|
||||
export function isCacheDebuggingEnabled(): boolean {
|
||||
return process.env['GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED'] ? true : false
|
||||
}
|
||||
|
||||
export function isCacheCleanupEnabled(): boolean {
|
||||
return getBooleanInput('gradle-home-cache-cleanup')
|
||||
}
|
||||
|
||||
export function getCacheEncryptionKey(): string {
|
||||
return core.getInput('cache-encryption-key')
|
||||
}
|
||||
|
||||
export function getCacheIncludes(): string[] {
|
||||
return core.getMultilineInput('gradle-home-cache-includes')
|
||||
}
|
||||
|
||||
export function getCacheExcludes(): string[] {
|
||||
return core.getMultilineInput('gradle-home-cache-excludes')
|
||||
}
|
||||
|
||||
export function getBuildRootDirectory(): string {
|
||||
return core.getInput('build-root-directory')
|
||||
}
|
||||
|
||||
export function getGradleVersion(): string {
|
||||
return core.getInput('gradle-version')
|
||||
}
|
||||
|
||||
export function getGradleExecutable(): string {
|
||||
return core.getInput('gradle-executable')
|
||||
}
|
||||
|
||||
export function getArguments(): string[] {
|
||||
const input = core.getInput('arguments')
|
||||
return parseArgsStringToArgv(input)
|
||||
}
|
||||
|
||||
// Internal parameters
|
||||
export function getJobMatrix(): string {
|
||||
return core.getInput('workflow-job-context')
|
||||
}
|
||||
|
||||
export function getGithubToken(): string {
|
||||
return core.getInput('github-token', {required: true})
|
||||
}
|
||||
|
||||
export function isJobSummaryEnabled(): boolean {
|
||||
return getBooleanInput('generate-job-summary', true)
|
||||
}
|
||||
|
||||
export function getJobSummaryOption(): JobSummaryOption {
|
||||
return parseJobSummaryOption('add-job-summary')
|
||||
}
|
||||
|
||||
export function getPRCommentOption(): JobSummaryOption {
|
||||
return parseJobSummaryOption('add-job-summary-as-pr-comment')
|
||||
}
|
||||
|
||||
function parseJobSummaryOption(paramName: string): JobSummaryOption {
|
||||
const val = core.getInput(paramName)
|
||||
switch (val.toLowerCase().trim()) {
|
||||
case 'never':
|
||||
return JobSummaryOption.Never
|
||||
case 'always':
|
||||
return JobSummaryOption.Always
|
||||
case 'on-failure':
|
||||
return JobSummaryOption.OnFailure
|
||||
}
|
||||
throw TypeError(`The value '${val}' is not valid for ${paramName}. Valid values are: [never, always, on-failure].`)
|
||||
}
|
||||
|
||||
export function getDependencyGraphOption(): DependencyGraphOption {
|
||||
const val = core.getInput('dependency-graph')
|
||||
switch (val.toLowerCase().trim()) {
|
||||
case 'disabled':
|
||||
return DependencyGraphOption.Disabled
|
||||
case 'generate':
|
||||
return DependencyGraphOption.Generate
|
||||
case 'generate-and-submit':
|
||||
return DependencyGraphOption.GenerateAndSubmit
|
||||
case 'generate-and-upload':
|
||||
return DependencyGraphOption.GenerateAndUpload
|
||||
case 'download-and-submit':
|
||||
return DependencyGraphOption.DownloadAndSubmit
|
||||
}
|
||||
throw TypeError(
|
||||
`The value '${val}' is not valid for 'dependency-graph'. Valid values are: [disabled, generate, generate-and-submit, generate-and-upload, download-and-submit]. The default value is 'disabled'.`
|
||||
)
|
||||
}
|
||||
|
||||
export function getArtifactRetentionDays(): number {
|
||||
const val = core.getInput('artifact-retention-days')
|
||||
return parseNumericInput('artifact-retention-days', val, 0)
|
||||
// Zero indicates that the default repository settings should be used
|
||||
}
|
||||
|
||||
export function parseNumericInput(paramName: string, paramValue: string, paramDefault: number): number {
|
||||
if (paramValue.length === 0) {
|
||||
return paramDefault
|
||||
}
|
||||
const numericValue = parseInt(paramValue)
|
||||
if (isNaN(numericValue)) {
|
||||
throw TypeError(`The value '${paramValue}' is not a valid numeric value for '${paramName}'.`)
|
||||
}
|
||||
return numericValue
|
||||
}
|
||||
|
||||
function getBooleanInput(paramName: string, paramDefault = false): boolean {
|
||||
const paramValue = core.getInput(paramName)
|
||||
switch (paramValue.toLowerCase().trim()) {
|
||||
case '':
|
||||
return paramDefault
|
||||
case 'false':
|
||||
return false
|
||||
case 'true':
|
||||
return true
|
||||
}
|
||||
throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`)
|
||||
}
|
||||
|
||||
export enum DependencyGraphOption {
|
||||
Disabled = 'disabled',
|
||||
Generate = 'generate',
|
||||
GenerateAndSubmit = 'generate-and-submit',
|
||||
GenerateAndUpload = 'generate-and-upload',
|
||||
DownloadAndSubmit = 'download-and-submit'
|
||||
}
|
||||
|
||||
export enum JobSummaryOption {
|
||||
Never = 'never',
|
||||
Always = 'always',
|
||||
OnFailure = 'on-failure'
|
||||
}
|
@@ -1,45 +1,94 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
|
||||
import {RequestError} from '@octokit/request-error'
|
||||
|
||||
import * as params from './input-params'
|
||||
import {BuildResult} from './build-results'
|
||||
import {writeCachingReport, CacheListener, logCachingReport} from './cache-reporting'
|
||||
import {CacheListener, generateCachingReport} from './cache-reporting'
|
||||
|
||||
export async function writeJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> {
|
||||
core.info('Writing job summary')
|
||||
export async function generateJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> {
|
||||
const summaryTable = renderSummaryTable(buildResults)
|
||||
const cachingReport = generateCachingReport(cacheListener)
|
||||
|
||||
if (buildResults.length === 0) {
|
||||
core.debug('No Gradle build results found. Summary table will not be generated.')
|
||||
if (shouldGenerateJobSummary(buildResults)) {
|
||||
core.info('Generating Job Summary')
|
||||
|
||||
core.summary.addRaw(summaryTable)
|
||||
core.summary.addRaw(cachingReport)
|
||||
await core.summary.write()
|
||||
} else {
|
||||
writeSummaryTable(buildResults)
|
||||
core.info('============================')
|
||||
core.info(summaryTable)
|
||||
core.info('============================')
|
||||
core.info(cachingReport)
|
||||
core.info('============================')
|
||||
}
|
||||
|
||||
writeCachingReport(cacheListener)
|
||||
|
||||
await core.summary.write()
|
||||
if (shouldAddPRComment(buildResults)) {
|
||||
await addPRComment(summaryTable)
|
||||
}
|
||||
}
|
||||
|
||||
export async function logJobSummary(buildResults: BuildResult[], cacheListener: CacheListener): Promise<void> {
|
||||
if (buildResults.length === 0) {
|
||||
core.debug('No Gradle build results found. Summary table will not be logged.')
|
||||
} else {
|
||||
logSummaryTable(buildResults)
|
||||
async function addPRComment(jobSummary: string): Promise<void> {
|
||||
const context = github.context
|
||||
if (context.payload.pull_request == null) {
|
||||
core.info('No pull_request trigger: not adding PR comment')
|
||||
return
|
||||
}
|
||||
|
||||
logCachingReport(cacheListener)
|
||||
const pull_request_number = context.payload.pull_request.number
|
||||
core.info(`Adding Job Summary as comment to PR #${pull_request_number}.`)
|
||||
|
||||
const prComment = `<h3>Job Summary for gradle-build-action</h3>
|
||||
<h5>${github.context.workflow} :: <em>${github.context.job}</em></h5>
|
||||
|
||||
${jobSummary}`
|
||||
|
||||
const github_token = params.getGithubToken()
|
||||
const octokit = github.getOctokit(github_token)
|
||||
try {
|
||||
await octokit.rest.issues.createComment({
|
||||
...context.repo,
|
||||
issue_number: pull_request_number,
|
||||
body: prComment
|
||||
})
|
||||
} catch (error) {
|
||||
if (error instanceof RequestError) {
|
||||
core.warning(buildWarningMessage(error))
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeSummaryTable(results: BuildResult[]): void {
|
||||
core.summary.addHeading('Gradle Builds', 3)
|
||||
function buildWarningMessage(error: RequestError): string {
|
||||
const mainWarning = `Failed to generate PR comment.\n${String(error)}`
|
||||
if (error.message === 'Resource not accessible by integration') {
|
||||
return `${mainWarning}
|
||||
Please ensure that the 'pull-requests: write' permission is available for the workflow job.
|
||||
Note that this permission is never available for a workflow triggered from a repository fork.
|
||||
`
|
||||
}
|
||||
return mainWarning
|
||||
}
|
||||
|
||||
core.summary.addRaw(`
|
||||
function renderSummaryTable(results: BuildResult[]): string {
|
||||
if (results.length === 0) {
|
||||
return 'No Gradle build results detected.'
|
||||
}
|
||||
|
||||
return `
|
||||
<table>
|
||||
<tr>
|
||||
<th>Root Project</th>
|
||||
<th>Gradle Root Project</th>
|
||||
<th>Requested Tasks</th>
|
||||
<th>Gradle Version</th>
|
||||
<th>Build Outcome</th>
|
||||
<th>Build Scan™</th>
|
||||
<th>Build Scan®</th>
|
||||
</tr>${results.map(result => renderBuildResultRow(result)).join('')}
|
||||
</table>
|
||||
`)
|
||||
`
|
||||
}
|
||||
|
||||
function renderBuildResultRow(result: BuildResult): string {
|
||||
@@ -72,23 +121,37 @@ function renderBuildScan(result: BuildResult): string {
|
||||
}
|
||||
|
||||
function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetUrl: string): string {
|
||||
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%E2%84%A2-${outcomeText}-${outcomeColor}?logo=Gradle`
|
||||
const badgeUrl = `https://img.shields.io/badge/Build%20Scan%C2%AE-${outcomeText}-${outcomeColor}?logo=Gradle`
|
||||
const badgeHtml = `<img src="${badgeUrl}" alt="Build Scan ${outcomeText}" />`
|
||||
return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`
|
||||
}
|
||||
|
||||
function logSummaryTable(results: BuildResult[]): void {
|
||||
core.info('============================')
|
||||
core.info('Gradle Builds')
|
||||
core.info('----------------------------')
|
||||
core.info('Root Project | Requested Tasks | Gradle Version | Build Outcome | Build Scan™')
|
||||
core.info('----------------------------')
|
||||
for (const result of results) {
|
||||
core.info(
|
||||
`${result.rootProjectName} | ${result.requestedTasks} | ${result.gradleVersion} | ${
|
||||
result.buildFailed ? 'FAILED' : 'SUCCESS'
|
||||
} | ${result.buildScanFailed ? 'Publish failed' : result.buildScanUri}`
|
||||
)
|
||||
function shouldGenerateJobSummary(buildResults: BuildResult[]): boolean {
|
||||
// Check if Job Summary is supported on this platform
|
||||
if (!process.env[SUMMARY_ENV_VAR]) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if Job Summary is disabled using the deprecated input
|
||||
if (!params.isJobSummaryEnabled()) {
|
||||
return false
|
||||
}
|
||||
|
||||
return shouldAddJobSummary(params.getJobSummaryOption(), buildResults)
|
||||
}
|
||||
|
||||
function shouldAddPRComment(buildResults: BuildResult[]): boolean {
|
||||
return shouldAddJobSummary(params.getPRCommentOption(), buildResults)
|
||||
}
|
||||
|
||||
function shouldAddJobSummary(option: params.JobSummaryOption, buildResults: BuildResult[]): boolean {
|
||||
switch (option) {
|
||||
case params.JobSummaryOption.Always:
|
||||
return true
|
||||
case params.JobSummaryOption.Never:
|
||||
return false
|
||||
case params.JobSummaryOption.OnFailure:
|
||||
core.info(`Got these build results: ${JSON.stringify(buildResults)}`)
|
||||
return buildResults.some(result => result.buildFailed)
|
||||
}
|
||||
core.info('============================')
|
||||
}
|
||||
|
48
src/main.ts
48
src/main.ts
@@ -1,30 +1,26 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as path from 'path'
|
||||
import {parseArgsStringToArgv} from 'string-argv'
|
||||
|
||||
import * as setupGradle from './setup-gradle'
|
||||
import * as execution from './execution'
|
||||
import * as provision from './provision'
|
||||
import * as provisioner from './provision'
|
||||
import * as layout from './repository-layout'
|
||||
import * as params from './input-params'
|
||||
|
||||
/**
|
||||
* The main entry point for the action, called by Github Actions for the step.
|
||||
*/
|
||||
export async function run(): Promise<void> {
|
||||
try {
|
||||
const workspaceDirectory = process.env[`GITHUB_WORKSPACE`] || ''
|
||||
const buildRootDirectory = resolveBuildRootDirectory(workspaceDirectory)
|
||||
// Configure Gradle environment (Gradle User Home)
|
||||
await setupGradle.setup()
|
||||
|
||||
await setupGradle.setup(buildRootDirectory)
|
||||
|
||||
const executable = await provisionGradle(workspaceDirectory)
|
||||
// executable will be undefined if using Gradle wrapper
|
||||
if (executable !== undefined) {
|
||||
core.addPath(path.dirname(executable))
|
||||
}
|
||||
// Download and install Gradle if required
|
||||
const executable = await provisioner.provisionGradle()
|
||||
|
||||
// Only execute if arguments have been provided
|
||||
const args: string[] = parseCommandLineArguments()
|
||||
const args: string[] = params.getArguments()
|
||||
if (args.length > 0) {
|
||||
const buildRootDirectory = layout.buildRootDirectory()
|
||||
await execution.executeGradleBuild(executable, buildRootDirectory, args)
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -36,29 +32,3 @@ export async function run(): Promise<void> {
|
||||
}
|
||||
|
||||
run()
|
||||
|
||||
async function provisionGradle(workspaceDirectory: string): Promise<string | undefined> {
|
||||
const gradleVersion = core.getInput('gradle-version')
|
||||
if (gradleVersion !== '' && gradleVersion !== 'wrapper') {
|
||||
return path.resolve(await provision.gradleVersion(gradleVersion))
|
||||
}
|
||||
|
||||
const gradleExecutable = core.getInput('gradle-executable')
|
||||
if (gradleExecutable !== '') {
|
||||
return path.resolve(workspaceDirectory, gradleExecutable)
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
function resolveBuildRootDirectory(baseDirectory: string): string {
|
||||
const buildRootDirectory = core.getInput('build-root-directory')
|
||||
const resolvedBuildRootDirectory =
|
||||
buildRootDirectory === '' ? path.resolve(baseDirectory) : path.resolve(baseDirectory, buildRootDirectory)
|
||||
return resolvedBuildRootDirectory
|
||||
}
|
||||
|
||||
function parseCommandLineArguments(): string[] {
|
||||
const input = core.getInput('arguments')
|
||||
return parseArgsStringToArgv(input)
|
||||
}
|
||||
|
@@ -7,14 +7,43 @@ import * as cache from '@actions/cache'
|
||||
import * as toolCache from '@actions/tool-cache'
|
||||
|
||||
import * as gradlew from './gradlew'
|
||||
import * as params from './input-params'
|
||||
import * as layout from './repository-layout'
|
||||
import {handleCacheFailure, isCacheDisabled, isCacheReadOnly} from './cache-utils'
|
||||
|
||||
const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'
|
||||
|
||||
/**
|
||||
* @return Gradle executable path
|
||||
* Install any configured version of Gradle, adding the executable to the PATH.
|
||||
* @return Installed Gradle executable or undefined if no version configured.
|
||||
*/
|
||||
export async function gradleVersion(version: string): Promise<string> {
|
||||
export async function provisionGradle(): Promise<string | undefined> {
|
||||
const gradleVersion = params.getGradleVersion()
|
||||
if (gradleVersion !== '' && gradleVersion !== 'wrapper') {
|
||||
return addToPath(path.resolve(await installGradle(gradleVersion)))
|
||||
}
|
||||
|
||||
const gradleExecutable = params.getGradleExecutable()
|
||||
if (gradleExecutable !== '') {
|
||||
const workspaceDirectory = layout.workspaceDirectory()
|
||||
return addToPath(path.resolve(workspaceDirectory, gradleExecutable))
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
async function addToPath(executable: string): Promise<string> {
|
||||
core.addPath(path.dirname(executable))
|
||||
return executable
|
||||
}
|
||||
|
||||
async function installGradle(version: string): Promise<string> {
|
||||
const versionInfo = await resolveGradleVersion(version)
|
||||
core.setOutput('gradle-version', versionInfo.version)
|
||||
return installGradleVersion(versionInfo)
|
||||
}
|
||||
|
||||
async function resolveGradleVersion(version: string): Promise<GradleVersionInfo> {
|
||||
switch (version) {
|
||||
case 'current':
|
||||
return gradleCurrent()
|
||||
@@ -32,36 +61,33 @@ export async function gradleVersion(version: string): Promise<string> {
|
||||
}
|
||||
}
|
||||
|
||||
async function gradleCurrent(): Promise<string> {
|
||||
const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/current`)
|
||||
return provisionGradle(versionInfo)
|
||||
async function gradleCurrent(): Promise<GradleVersionInfo> {
|
||||
return await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/current`)
|
||||
}
|
||||
|
||||
async function gradleReleaseCandidate(): Promise<string> {
|
||||
async function gradleReleaseCandidate(): Promise<GradleVersionInfo> {
|
||||
const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-candidate`)
|
||||
if (versionInfo && versionInfo.version && versionInfo.downloadUrl) {
|
||||
return provisionGradle(versionInfo)
|
||||
return versionInfo
|
||||
}
|
||||
core.info('No current release-candidate found, will fallback to current')
|
||||
return gradleCurrent()
|
||||
}
|
||||
|
||||
async function gradleNightly(): Promise<string> {
|
||||
const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/nightly`)
|
||||
return provisionGradle(versionInfo)
|
||||
async function gradleNightly(): Promise<GradleVersionInfo> {
|
||||
return await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/nightly`)
|
||||
}
|
||||
|
||||
async function gradleReleaseNightly(): Promise<string> {
|
||||
const versionInfo = await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-nightly`)
|
||||
return provisionGradle(versionInfo)
|
||||
async function gradleReleaseNightly(): Promise<GradleVersionInfo> {
|
||||
return await gradleVersionDeclaration(`${gradleVersionsBaseUrl}/release-nightly`)
|
||||
}
|
||||
|
||||
async function gradle(version: string): Promise<string> {
|
||||
async function gradle(version: string): Promise<GradleVersionInfo> {
|
||||
const versionInfo = await findGradleVersionDeclaration(version)
|
||||
if (!versionInfo) {
|
||||
throw new Error(`Gradle version ${version} does not exists`)
|
||||
}
|
||||
return provisionGradle(versionInfo)
|
||||
return versionInfo
|
||||
}
|
||||
|
||||
async function gradleVersionDeclaration(url: string): Promise<GradleVersionInfo> {
|
||||
@@ -75,7 +101,7 @@ async function findGradleVersionDeclaration(version: string): Promise<GradleVers
|
||||
})
|
||||
}
|
||||
|
||||
async function provisionGradle(versionInfo: GradleVersionInfo): Promise<string> {
|
||||
async function installGradleVersion(versionInfo: GradleVersionInfo): Promise<string> {
|
||||
return core.group(`Provision Gradle ${versionInfo.version}`, async () => {
|
||||
return locateGradleAndDownloadIfRequired(versionInfo)
|
||||
})
|
||||
|
16
src/repository-layout.ts
Normal file
16
src/repository-layout.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as params from './input-params'
|
||||
import * as path from 'path'
|
||||
|
||||
export function workspaceDirectory(): string {
|
||||
return process.env[`GITHUB_WORKSPACE`] || ''
|
||||
}
|
||||
|
||||
export function buildRootDirectory(): string {
|
||||
const baseDirectory = workspaceDirectory()
|
||||
const buildRootDirectoryInput = params.getBuildRootDirectory()
|
||||
const resolvedBuildRootDirectory =
|
||||
buildRootDirectoryInput === ''
|
||||
? path.resolve(baseDirectory)
|
||||
: path.resolve(baseDirectory, buildRootDirectoryInput)
|
||||
return resolvedBuildRootDirectory
|
||||
}
|
@@ -51,9 +51,15 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
|
||||
return
|
||||
}
|
||||
|
||||
def buildResultsDir = new File(runnerTempDir, ".build-results")
|
||||
buildResultsDir.mkdirs()
|
||||
def buildResultsFile = new File(buildResultsDir, githubActionStep + getParameters().getInvocationId().get() + ".json")
|
||||
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
||||
try {
|
||||
def buildResultsDir = new File(runnerTempDir, ".build-results")
|
||||
buildResultsDir.mkdirs()
|
||||
def buildResultsFile = new File(buildResultsDir, githubActionStep + getParameters().getInvocationId().get() + ".json")
|
||||
if (!buildResultsFile.exists()) {
|
||||
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
||||
}
|
||||
} catch (Exception e) {
|
||||
println "\ngradle-build-action failed to write build-results file. Will continue.\n> ${e.getLocalizedMessage()}"
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,24 +16,29 @@ if (isTopLevelBuild) {
|
||||
if (atLeastGradle6) {
|
||||
def useBuildService = version >= GradleVersion.version("6.6")
|
||||
settingsEvaluated { settings ->
|
||||
// The `buildScanPublished` hook is the only way to capture the build scan URI.
|
||||
if (settings.pluginManager.hasPlugin("com.gradle.enterprise")) {
|
||||
captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject, invocationId)
|
||||
}
|
||||
// We also need to add hooks in case the plugin is applied but no build scan is published
|
||||
// By default, use standard mechanisms to capture build results
|
||||
if (useBuildService) {
|
||||
captureUsingBuildService(settings, invocationId)
|
||||
} else {
|
||||
captureUsingBuildFinished(gradle, invocationId)
|
||||
}
|
||||
|
||||
// The `buildScanPublished` hook allows the capture of the Build Scan URI.
|
||||
// Results captured this way will overwrite any results from the other mechanism.
|
||||
settings.pluginManager.withPlugin("com.gradle.enterprise") {
|
||||
captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject, invocationId)
|
||||
}
|
||||
}
|
||||
} else if (atLeastGradle3) {
|
||||
projectsEvaluated { gradle ->
|
||||
if (gradle.rootProject.pluginManager.hasPlugin("com.gradle.build-scan")) {
|
||||
// By default, use 'buildFinished' to capture build results
|
||||
captureUsingBuildFinished(gradle, invocationId)
|
||||
|
||||
// The `buildScanPublished` hook allows the capture of the Build Scan URI.
|
||||
// Results captured this way will overwrite any results from 'buildFinished'.
|
||||
gradle.rootProject.pluginManager.withPlugin("com.gradle.build-scan") {
|
||||
captureUsingBuildScanPublished(gradle.rootProject.extensions["buildScan"], gradle.rootProject, invocationId)
|
||||
}
|
||||
// We need to capture in buildFinished in case the plugin is applied but no build scan is published
|
||||
captureUsingBuildFinished(gradle, invocationId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +55,13 @@ def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId
|
||||
buildResults.setBuildScanUri(buildScan.buildScanUri.toASCIIString())
|
||||
buildResults.writeToResultsFile(true)
|
||||
|
||||
println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
|
||||
def githubOutput = System.getenv("GITHUB_OUTPUT")
|
||||
if (githubOutput) {
|
||||
new File(githubOutput) << "build-scan-url=${buildScan.buildScanUri}\n"
|
||||
} else {
|
||||
// Retained for compatibility with older GitHub Enterprise versions
|
||||
println("::set-output name=build-scan-url::${buildScan.buildScanUri}")
|
||||
}
|
||||
}
|
||||
|
||||
onError { error ->
|
||||
@@ -62,17 +73,16 @@ def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId
|
||||
|
||||
def captureUsingBuildFinished(gradle, invocationId) {
|
||||
gradle.buildFinished { result ->
|
||||
println "Got buildFinished: ${result}"
|
||||
def buildResults = new BuildResults(invocationId, gradle, gradle.rootProject)
|
||||
buildResults.setBuildResult(result)
|
||||
|
||||
buildResults.writeToResultsFile(false)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def captureUsingBuildService(settings, invocationId) {
|
||||
gradle.ext.invocationId = invocationId
|
||||
apply from: 'build-result-capture-service.plugin.groovy'
|
||||
apply from: 'gradle-build-action.build-result-capture-service.plugin.groovy'
|
||||
}
|
||||
|
||||
class BuildResults {
|
||||
@@ -112,17 +122,22 @@ class BuildResults {
|
||||
return
|
||||
}
|
||||
|
||||
def buildResultsDir = new File(runnerTempDir, ".build-results")
|
||||
buildResultsDir.mkdirs()
|
||||
def buildResultsFile = new File(buildResultsDir, githubActionStep + invocationId + ".json")
|
||||
try {
|
||||
def buildResultsDir = new File(runnerTempDir, ".build-results")
|
||||
buildResultsDir.mkdirs()
|
||||
def buildResultsFile = new File(buildResultsDir, githubActionStep + invocationId + ".json")
|
||||
|
||||
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
|
||||
if (buildResultsFile.exists()) {
|
||||
if (overwrite) {
|
||||
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
|
||||
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
|
||||
if (buildResultsFile.exists()) {
|
||||
if (overwrite) {
|
||||
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
|
||||
}
|
||||
} else {
|
||||
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
||||
}
|
||||
} else {
|
||||
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
|
||||
|
||||
} catch (Exception e) {
|
||||
println "\ngradle-build-action failed to write build-results file. Will continue.\n> ${e.getLocalizedMessage()}"
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
buildscript {
|
||||
def getInputParam = { String name ->
|
||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||
}
|
||||
def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url') ?: 'https://plugins.gradle.org/m2'
|
||||
|
||||
repositories {
|
||||
maven { url pluginRepositoryUrl }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.gradle:github-dependency-graph-gradle-plugin:1.0.0"
|
||||
}
|
||||
}
|
||||
apply plugin: org.gradle.github.GitHubDependencyGraphPlugin
|
@@ -0,0 +1,65 @@
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
// Only run when dependency graph is explicitly enabled
|
||||
if (getVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED') != "true") {
|
||||
return
|
||||
}
|
||||
|
||||
// Do not run for unsupported versions of Gradle
|
||||
if (GradleVersion.current().baseVersion < GradleVersion.version("5.0")) {
|
||||
println "::warning::Dependency Graph is not supported for Gradle versions < 5.0. No dependency snapshot will be generated."
|
||||
return
|
||||
}
|
||||
|
||||
// Attempt to find a unique job correlator to use based on the environment variable
|
||||
// This is only required for top-level builds
|
||||
def isTopLevelBuild = gradle.getParent() == null
|
||||
if (isTopLevelBuild) {
|
||||
def reportFile = getUniqueReportFile(getVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR'))
|
||||
|
||||
if (reportFile == null) {
|
||||
println "::warning::No dependency snapshot generated for step. Could not determine unique job correlator - specify GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR var for this step."
|
||||
return
|
||||
}
|
||||
|
||||
def githubOutput = System.getenv("GITHUB_OUTPUT")
|
||||
if (githubOutput) {
|
||||
new File(githubOutput) << "dependency-graph-file=${reportFile.absolutePath}\n"
|
||||
}
|
||||
|
||||
println "Generating dependency graph into '${reportFile}'"
|
||||
}
|
||||
|
||||
apply from: 'gradle-build-action.github-dependency-graph-gradle-plugin-apply.groovy'
|
||||
|
||||
/**
|
||||
* Using the supplied jobCorrelator value:
|
||||
* - Checks if report file already exists
|
||||
* - If so, tries to find a unique value that does not yet have a corresponding report file.
|
||||
* - When found, this value is set as a System property override.
|
||||
*/
|
||||
File getUniqueReportFile(String jobCorrelator) {
|
||||
def reportDir = getVariable('DEPENDENCY_GRAPH_REPORT_DIR')
|
||||
def reportFile = new File(reportDir, jobCorrelator + ".json")
|
||||
if (!reportFile.exists()) return reportFile
|
||||
|
||||
// Try at most 100 suffixes
|
||||
for (int i = 1; i < 100; i++) {
|
||||
def candidateCorrelator = jobCorrelator + "-" + i
|
||||
def candidateFile = new File(reportDir, candidateCorrelator + ".json")
|
||||
if (!candidateFile.exists()) {
|
||||
System.properties['GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR'] = candidateCorrelator
|
||||
return candidateFile
|
||||
}
|
||||
}
|
||||
|
||||
// Could not determine unique job correlator
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the environment variable value, or equivalent system property (if set)
|
||||
*/
|
||||
String getVariable(String name) {
|
||||
return System.properties[name] ?: System.getenv(name)
|
||||
}
|
@@ -0,0 +1,192 @@
|
||||
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
|
||||
|
||||
// conditionally apply the GE / Build Scan plugin to the classpath so it can be applied to the build further down in this script
|
||||
initscript {
|
||||
def isTopLevelBuild = !gradle.parent
|
||||
if (!isTopLevelBuild) {
|
||||
return
|
||||
}
|
||||
|
||||
def getInputParam = { String name ->
|
||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||
}
|
||||
|
||||
// finish early if injection is disabled
|
||||
def gradleInjectionEnabled = getInputParam("gradle-enterprise.injection-enabled")
|
||||
if (gradleInjectionEnabled != "true") {
|
||||
return
|
||||
}
|
||||
|
||||
def pluginRepositoryUrl = getInputParam('gradle-enterprise.plugin-repository.url')
|
||||
def gePluginVersion = getInputParam('gradle-enterprise.plugin.version')
|
||||
def ccudPluginVersion = getInputParam('gradle-enterprise.ccud-plugin.version')
|
||||
|
||||
def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0')
|
||||
def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0')
|
||||
|
||||
if (gePluginVersion || ccudPluginVersion && atLeastGradle4) {
|
||||
pluginRepositoryUrl = pluginRepositoryUrl ?: 'https://plugins.gradle.org/m2'
|
||||
logger.quiet("Gradle Enterprise plugins resolution: $pluginRepositoryUrl")
|
||||
|
||||
repositories {
|
||||
maven { url pluginRepositoryUrl }
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
if (gePluginVersion) {
|
||||
classpath atLeastGradle5 ?
|
||||
"com.gradle:gradle-enterprise-gradle-plugin:$gePluginVersion" :
|
||||
"com.gradle:build-scan-plugin:1.16"
|
||||
}
|
||||
|
||||
if (ccudPluginVersion && atLeastGradle4) {
|
||||
classpath "com.gradle:common-custom-user-data-gradle-plugin:$ccudPluginVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
|
||||
def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin'
|
||||
|
||||
def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise'
|
||||
def GRADLE_ENTERPRISE_PLUGIN_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin'
|
||||
def GRADLE_ENTERPRISE_EXTENSION_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterpriseExtension'
|
||||
def CI_AUTO_INJECTION_CUSTOM_VALUE_NAME = 'CI auto injection'
|
||||
def CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE = 'gradle-build-action'
|
||||
def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin'
|
||||
def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin'
|
||||
|
||||
def isTopLevelBuild = !gradle.parent
|
||||
if (!isTopLevelBuild) {
|
||||
return
|
||||
}
|
||||
|
||||
def getInputParam = { String name ->
|
||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||
}
|
||||
|
||||
// finish early if injection is disabled
|
||||
def gradleInjectionEnabled = getInputParam("gradle-enterprise.injection-enabled")
|
||||
if (gradleInjectionEnabled != "true") {
|
||||
return
|
||||
}
|
||||
|
||||
def geUrl = getInputParam('gradle-enterprise.url')
|
||||
def geAllowUntrustedServer = Boolean.parseBoolean(getInputParam('gradle-enterprise.allow-untrusted-server'))
|
||||
def geEnforceUrl = Boolean.parseBoolean(getInputParam('gradle-enterprise.enforce-url'))
|
||||
def buildScanUploadInBackground = Boolean.parseBoolean(getInputParam('gradle-enterprise.build-scan.upload-in-background'))
|
||||
def gePluginVersion = getInputParam('gradle-enterprise.plugin.version')
|
||||
def ccudPluginVersion = getInputParam('gradle-enterprise.ccud-plugin.version')
|
||||
|
||||
def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0')
|
||||
|
||||
// finish early if configuration parameters passed in via system properties are not valid/supported
|
||||
if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) {
|
||||
logger.warn("Common Custom User Data Gradle plugin must be at least 1.7. Configured version is $ccudPluginVersion.")
|
||||
return
|
||||
}
|
||||
|
||||
// register buildScanPublished listener and optionally apply the GE / Build Scan plugin
|
||||
if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
||||
rootProject {
|
||||
buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming ->
|
||||
def resolutionResult = incoming.resolutionResult
|
||||
|
||||
if (gePluginVersion) {
|
||||
def scanPluginComponent = resolutionResult.allComponents.find {
|
||||
it.moduleVersion.with { group == "com.gradle" && (name == "build-scan-plugin" || name == "gradle-enterprise-gradle-plugin") }
|
||||
}
|
||||
if (!scanPluginComponent) {
|
||||
logger.quiet("Applying $BUILD_SCAN_PLUGIN_CLASS via init script")
|
||||
logger.quiet("Connection to Gradle Enterprise: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
|
||||
applyPluginExternally(pluginManager, BUILD_SCAN_PLUGIN_CLASS)
|
||||
buildScan.server = geUrl
|
||||
buildScan.allowUntrustedServer = geAllowUntrustedServer
|
||||
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) {
|
||||
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
|
||||
afterEvaluate {
|
||||
logger.quiet("Enforcing Gradle Enterprise: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
|
||||
buildScan.server = geUrl
|
||||
buildScan.allowUntrustedServer = geAllowUntrustedServer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ccudPluginVersion && atLeastGradle4) {
|
||||
def ccudPluginComponent = resolutionResult.allComponents.find {
|
||||
it.moduleVersion.with { group == "com.gradle" && name == "common-custom-user-data-gradle-plugin" }
|
||||
}
|
||||
if (!ccudPluginComponent) {
|
||||
logger.quiet("Applying $CCUD_PLUGIN_CLASS via init script")
|
||||
pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gradle.settingsEvaluated { settings ->
|
||||
if (gePluginVersion) {
|
||||
if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID)) {
|
||||
logger.quiet("Applying $GRADLE_ENTERPRISE_PLUGIN_CLASS via init script")
|
||||
logger.quiet("Connection to Gradle Enterprise: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
|
||||
applyPluginExternally(settings.pluginManager, GRADLE_ENTERPRISE_PLUGIN_CLASS)
|
||||
extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS).collect { settings[it.name] }.each { ext ->
|
||||
ext.server = geUrl
|
||||
ext.allowUntrustedServer = geAllowUntrustedServer
|
||||
ext.buildScan.publishAlways()
|
||||
ext.buildScan.uploadInBackground = buildScanUploadInBackground
|
||||
ext.buildScan.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
if (geUrl && geEnforceUrl) {
|
||||
extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS).collect { settings[it.name] }.each { ext ->
|
||||
logger.quiet("Enforcing Gradle Enterprise: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
|
||||
ext.server = geUrl
|
||||
ext.allowUntrustedServer = geAllowUntrustedServer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ccudPluginVersion) {
|
||||
if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) {
|
||||
logger.quiet("Applying $CCUD_PLUGIN_CLASS via init script")
|
||||
settings.pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void applyPluginExternally(def pluginManager, String pluginClassName) {
|
||||
def externallyApplied = 'gradle.enterprise.externally-applied'
|
||||
def oldValue = System.getProperty(externallyApplied)
|
||||
System.setProperty(externallyApplied, 'true')
|
||||
try {
|
||||
pluginManager.apply(initscript.classLoader.loadClass(pluginClassName))
|
||||
} finally {
|
||||
if (oldValue == null) {
|
||||
System.clearProperty(externallyApplied)
|
||||
} else {
|
||||
System.setProperty(externallyApplied, oldValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static def extensionsWithPublicType(def container, String publicType) {
|
||||
container.extensions.extensionsSchema.elements.findAll { it.publicType.concreteClass.name == publicType }
|
||||
}
|
||||
|
||||
static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
|
||||
GradleVersion.version(versionUnderTest) < GradleVersion.version(referenceVersion)
|
||||
}
|
44
src/resources/toolchains.xml
Normal file
44
src/resources/toolchains.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<toolchains>
|
||||
<!-- JDK Toolchains installed by default on GitHub-hosted runners -->
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>8</version>
|
||||
<vendor>Eclipse Temurin</vendor>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>${env.JAVA_HOME_8_X64}</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>11</version>
|
||||
<vendor>Eclipse Temurin</vendor>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>${env.JAVA_HOME_11_X64}</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>17</version>
|
||||
<vendor>Eclipse Temurin</vendor>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>${env.JAVA_HOME_17_X64}</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>21</version>
|
||||
<vendor>Eclipse Temurin</vendor>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>${env.JAVA_HOME_21_X64}</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
</toolchains>
|
@@ -1,31 +1,25 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
|
||||
import * as path from 'path'
|
||||
import * as os from 'os'
|
||||
import * as caches from './caches'
|
||||
import * as layout from './repository-layout'
|
||||
import * as params from './input-params'
|
||||
import * as dependencyGraph from './dependency-graph'
|
||||
import * as jobSummary from './job-summary'
|
||||
|
||||
import {logJobSummary, writeJobSummary} from './job-summary'
|
||||
import {loadBuildResults} from './build-results'
|
||||
import {CacheListener} from './cache-reporting'
|
||||
import {DaemonController} from './daemon-controller'
|
||||
|
||||
const GRADLE_SETUP_VAR = 'GRADLE_BUILD_ACTION_SETUP_COMPLETED'
|
||||
const USER_HOME = 'USER_HOME'
|
||||
const GRADLE_USER_HOME = 'GRADLE_USER_HOME'
|
||||
const CACHE_LISTENER = 'CACHE_LISTENER'
|
||||
const JOB_SUMMARY_ENABLED_PARAMETER = 'generate-job-summary'
|
||||
|
||||
function shouldGenerateJobSummary(): boolean {
|
||||
// Check if Job Summary is supported on this platform
|
||||
if (!process.env[SUMMARY_ENV_VAR]) {
|
||||
return false
|
||||
}
|
||||
|
||||
return core.getBooleanInput(JOB_SUMMARY_ENABLED_PARAMETER)
|
||||
}
|
||||
|
||||
export async function setup(buildRootDirectory: string): Promise<void> {
|
||||
const gradleUserHome = await determineGradleUserHome(buildRootDirectory)
|
||||
export async function setup(): Promise<void> {
|
||||
const userHome = await determineUserHome()
|
||||
const gradleUserHome = await determineGradleUserHome()
|
||||
|
||||
// Bypass setup on all but first action step in workflow.
|
||||
if (process.env[GRADLE_SETUP_VAR]) {
|
||||
@@ -37,13 +31,16 @@ export async function setup(buildRootDirectory: string): Promise<void> {
|
||||
// Record setup complete: visible in post-action, to control action completion
|
||||
core.saveState(GRADLE_SETUP_VAR, true)
|
||||
|
||||
// Save the Gradle User Home for use in the post-action step.
|
||||
// Save the User Home and Gradle User Home for use in the post-action step.
|
||||
core.saveState(USER_HOME, userHome)
|
||||
core.saveState(GRADLE_USER_HOME, gradleUserHome)
|
||||
|
||||
const cacheListener = new CacheListener()
|
||||
await caches.restore(gradleUserHome, cacheListener)
|
||||
await caches.restore(userHome, gradleUserHome, cacheListener)
|
||||
|
||||
core.saveState(CACHE_LISTENER, cacheListener.stringify())
|
||||
|
||||
await dependencyGraph.setup(params.getDependencyGraphOption())
|
||||
}
|
||||
|
||||
export async function complete(): Promise<void> {
|
||||
@@ -51,26 +48,28 @@ export async function complete(): Promise<void> {
|
||||
core.info('Gradle setup post-action only performed for first gradle-build-action step in workflow.')
|
||||
return
|
||||
}
|
||||
core.info('In final post-action step, saving state and writing summary')
|
||||
core.info('In post-action step')
|
||||
|
||||
const buildResults = loadBuildResults()
|
||||
|
||||
const userHome = core.getState(USER_HOME)
|
||||
const gradleUserHome = core.getState(GRADLE_USER_HOME)
|
||||
const cacheListener: CacheListener = CacheListener.rehydrate(core.getState(CACHE_LISTENER))
|
||||
const daemonController = new DaemonController(buildResults)
|
||||
|
||||
await caches.save(gradleUserHome, cacheListener, daemonController)
|
||||
await caches.save(userHome, gradleUserHome, cacheListener, daemonController)
|
||||
|
||||
if (shouldGenerateJobSummary()) {
|
||||
await writeJobSummary(buildResults, cacheListener)
|
||||
} else {
|
||||
logJobSummary(buildResults, cacheListener)
|
||||
}
|
||||
await jobSummary.generateJobSummary(buildResults, cacheListener)
|
||||
|
||||
await dependencyGraph.complete(params.getDependencyGraphOption())
|
||||
|
||||
core.info('Completed post-action step')
|
||||
}
|
||||
|
||||
async function determineGradleUserHome(rootDir: string): Promise<string> {
|
||||
async function determineGradleUserHome(): Promise<string> {
|
||||
const customGradleUserHome = process.env['GRADLE_USER_HOME']
|
||||
if (customGradleUserHome) {
|
||||
const rootDir = layout.workspaceDirectory()
|
||||
return path.resolve(rootDir, customGradleUserHome)
|
||||
}
|
||||
|
||||
|
@@ -14,14 +14,13 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
testImplementation gradleTestKit()
|
||||
testImplementation 'org.spockframework:spock-core:2.1-groovy-3.0'
|
||||
testImplementation('org.spockframework:spock-junit4:2.1-groovy-3.0')
|
||||
testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0'
|
||||
testImplementation('org.spockframework:spock-junit4:2.3-groovy-3.0')
|
||||
|
||||
testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') {
|
||||
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
|
||||
}
|
||||
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.13.3'
|
||||
|
||||
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.16.0'
|
||||
}
|
||||
|
||||
test {
|
||||
|
BIN
test/init-scripts/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
test/init-scripts/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,5 +1,8 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionSha256Sum=591855b517fc635b9e04de1d05d5e76ada3f89f5fc76f87978d1b245b4f69225
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
31
test/init-scripts/gradlew
vendored
31
test/init-scripts/gradlew
vendored
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# 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/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# 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
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
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=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=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -193,6 +198,10 @@ if "$cygwin" || "$msys" ; then
|
||||
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, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
@@ -205,6 +214,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
15
test/init-scripts/gradlew.bat
vendored
15
test/init-scripts/gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +25,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
@@ -1 +1,14 @@
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.16.1"
|
||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "1.12.1"
|
||||
}
|
||||
|
||||
gradleEnterprise {
|
||||
buildScan {
|
||||
termsOfServiceUrl = "https://gradle.com/terms-of-service"
|
||||
termsOfServiceAgree = "yes"
|
||||
publishAlways()
|
||||
uploadInBackground = false
|
||||
}
|
||||
}
|
||||
rootProject.name = 'test-init-scripts'
|
||||
|
@@ -16,31 +16,34 @@ import java.nio.file.Files
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
class BaseInitScriptTest extends Specification {
|
||||
static final String GE_PLUGIN_VERSION = '3.16.1'
|
||||
static final String CCUD_PLUGIN_VERSION = '1.12.1'
|
||||
|
||||
static final TestGradleVersion GRADLE_3_5 = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9)
|
||||
static final TestGradleVersion GRADLE_4_0 = new TestGradleVersion(GradleVersion.version('4.0.2'), 7, 9)
|
||||
static final TestGradleVersion GRADLE_4_10 = new TestGradleVersion(GradleVersion.version('4.10.3'), 7, 10)
|
||||
static final TestGradleVersion GRADLE_5_0 = new TestGradleVersion(GradleVersion.version('5.0'), 8, 11)
|
||||
static final TestGradleVersion GRADLE_5_6 = new TestGradleVersion(GradleVersion.version('5.6.4'), 8, 12)
|
||||
static final TestGradleVersion GRADLE_6_0 = new TestGradleVersion(GradleVersion.version('6.0.1'), 8, 13)
|
||||
static final TestGradleVersion GRADLE_6_7 = new TestGradleVersion(GradleVersion.version('6.7'), 8, 15)
|
||||
static final TestGradleVersion GRADLE_7_0 = new TestGradleVersion(GradleVersion.version('7.0.2'), 8, 16)
|
||||
static final TestGradleVersion GRADLE_7_4 = new TestGradleVersion(GradleVersion.version('7.4.2'), 8, 17)
|
||||
static final 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_5_X = new TestGradleVersion(GradleVersion.version('5.6.4'), 8, 12)
|
||||
static final TestGradleVersion GRADLE_6_NO_BUILD_SERVICE = new TestGradleVersion(GradleVersion.version('6.5.1'), 8, 14)
|
||||
static final TestGradleVersion GRADLE_6_X = new TestGradleVersion(GradleVersion.version('6.9.4'), 8, 15)
|
||||
static final TestGradleVersion GRADLE_7_X = new TestGradleVersion(GradleVersion.version('7.6.2'), 8, 19)
|
||||
static final TestGradleVersion GRADLE_8_0 = new TestGradleVersion(GradleVersion.version('8.0.2'), 8, 19)
|
||||
static final TestGradleVersion GRADLE_8_X = new TestGradleVersion(GradleVersion.version('8.5'), 8, 19)
|
||||
|
||||
static final List<TestGradleVersion> ALL_VERSIONS = [
|
||||
GRADLE_3_5, // First version where TestKit supports environment variables
|
||||
GRADLE_4_0,
|
||||
GRADLE_4_10,
|
||||
GRADLE_5_0,
|
||||
GRADLE_5_6,
|
||||
GRADLE_6_0,
|
||||
GRADLE_6_7,
|
||||
GRADLE_7_0,
|
||||
GRADLE_7_4,
|
||||
GRADLE_3_X, // First version where TestKit supports environment variables
|
||||
GRADLE_4_X,
|
||||
GRADLE_5_X,
|
||||
GRADLE_6_NO_BUILD_SERVICE, // Last version without build service support
|
||||
GRADLE_6_X,
|
||||
GRADLE_7_X,
|
||||
GRADLE_8_0,
|
||||
GRADLE_8_X,
|
||||
]
|
||||
|
||||
static final List<TestGradleVersion> CONFIGURATION_CACHE_VERSIONS =
|
||||
[GRADLE_7_0, GRADLE_7_4]
|
||||
[GRADLE_7_X, GRADLE_8_0, GRADLE_8_X]
|
||||
|
||||
static final List<TestGradleVersion> SETTINGS_PLUGIN_VERSIONS =
|
||||
[GRADLE_6_X, GRADLE_7_X, GRADLE_8_0, GRADLE_8_X]
|
||||
|
||||
static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw'
|
||||
static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token'
|
||||
@@ -125,12 +128,17 @@ class BaseInitScriptTest extends Specification {
|
||||
buildFile << ''
|
||||
}
|
||||
|
||||
def declareGePluginApplication(GradleVersion gradleVersion) {
|
||||
settingsFile.text = maybeAddPluginsToSettings(gradleVersion) + settingsFile.text
|
||||
buildFile.text = maybeAddPluginsToRootProject(gradleVersion) + buildFile.text
|
||||
def declareGePluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) {
|
||||
settingsFile.text = maybeAddPluginsToSettings(gradleVersion, null, serverUrl) + settingsFile.text
|
||||
buildFile.text = maybeAddPluginsToRootProject(gradleVersion, null, serverUrl) + buildFile.text
|
||||
}
|
||||
|
||||
String maybeAddPluginsToSettings(GradleVersion gradleVersion) {
|
||||
def declareGePluginAndCcudPluginApplication(GradleVersion gradleVersion, URI serverUrl = mockScansServer.address) {
|
||||
settingsFile.text = maybeAddPluginsToSettings(gradleVersion, CCUD_PLUGIN_VERSION, serverUrl) + settingsFile.text
|
||||
buildFile.text = maybeAddPluginsToRootProject(gradleVersion, CCUD_PLUGIN_VERSION, serverUrl) + buildFile.text
|
||||
}
|
||||
|
||||
String maybeAddPluginsToSettings(GradleVersion gradleVersion, String ccudPluginVersion, URI serverUri) {
|
||||
if (gradleVersion < GradleVersion.version('5.0')) {
|
||||
'' // applied in build.gradle
|
||||
} else if (gradleVersion < GradleVersion.version('6.0')) {
|
||||
@@ -138,10 +146,11 @@ class BaseInitScriptTest extends Specification {
|
||||
} else {
|
||||
"""
|
||||
plugins {
|
||||
id 'com.gradle.enterprise' version '3.4.1'
|
||||
id 'com.gradle.enterprise' version '${GE_PLUGIN_VERSION}'
|
||||
${ccudPluginVersion ? "id 'com.gradle.common-custom-user-data-gradle-plugin' version '$ccudPluginVersion'" : ""}
|
||||
}
|
||||
gradleEnterprise {
|
||||
server = '$mockScansServer.address'
|
||||
server = '$serverUri'
|
||||
buildScan {
|
||||
publishAlways()
|
||||
}
|
||||
@@ -150,24 +159,26 @@ class BaseInitScriptTest extends Specification {
|
||||
}
|
||||
}
|
||||
|
||||
String maybeAddPluginsToRootProject(GradleVersion gradleVersion) {
|
||||
String maybeAddPluginsToRootProject(GradleVersion gradleVersion, String ccudPluginVersion, URI serverUrl) {
|
||||
if (gradleVersion < GradleVersion.version('5.0')) {
|
||||
"""
|
||||
plugins {
|
||||
id 'com.gradle.build-scan' version '1.16'
|
||||
${ccudPluginVersion ? "id 'com.gradle.common-custom-user-data-gradle-plugin' version '$ccudPluginVersion'" : ""}
|
||||
}
|
||||
buildScan {
|
||||
server = '$mockScansServer.address'
|
||||
server = '$serverUrl'
|
||||
publishAlways()
|
||||
}
|
||||
"""
|
||||
} else if (gradleVersion < GradleVersion.version('6.0')) {
|
||||
"""
|
||||
plugins {
|
||||
id 'com.gradle.build-scan' version '3.4.1'
|
||||
id 'com.gradle.build-scan' version '${GE_PLUGIN_VERSION}'
|
||||
${ccudPluginVersion ? "id 'com.gradle.common-custom-user-data-gradle-plugin' version '$ccudPluginVersion'" : ""}
|
||||
}
|
||||
gradleEnterprise {
|
||||
server = '$mockScansServer.address'
|
||||
server = '$serverUrl'
|
||||
buildScan {
|
||||
publishAlways()
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import groovy.json.JsonSlurper
|
||||
import static org.junit.Assume.assumeTrue
|
||||
|
||||
class TestBuildResultRecorder extends BaseInitScriptTest {
|
||||
def initScript = 'build-result-capture.init.gradle'
|
||||
def initScript = 'gradle-build-action.build-result-capture.init.gradle'
|
||||
|
||||
def "produces build results file for build with #testGradleVersion"() {
|
||||
assumeTrue testGradleVersion.compatibleWithCurrentJvm
|
||||
@@ -148,6 +148,51 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
||||
testGradleVersion << ALL_VERSIONS
|
||||
}
|
||||
|
||||
def "produces no build results file when RUNNER_TEMP dir is not a writable directory with #testGradleVersion"() {
|
||||
assumeTrue testGradleVersion.compatibleWithCurrentJvm
|
||||
|
||||
when:
|
||||
def invalidDir = new File(testProjectDir, 'invalid-runner-temp')
|
||||
invalidDir.createNewFile()
|
||||
|
||||
run(['help'], initScript, testGradleVersion.gradleVersion, [], [RUNNER_TEMP: invalidDir.absolutePath])
|
||||
|
||||
then:
|
||||
def buildResultsDir = new File(testProjectDir, '.build-results')
|
||||
assert !buildResultsDir.exists()
|
||||
|
||||
where:
|
||||
testGradleVersion << ALL_VERSIONS
|
||||
}
|
||||
|
||||
def "produces build results file with build scan when GE plugin is applied in settingsEvaluated"() {
|
||||
assumeTrue testGradleVersion.compatibleWithCurrentJvm
|
||||
|
||||
when:
|
||||
settingsFile.text = """
|
||||
plugins {
|
||||
id 'com.gradle.enterprise' version '3.16.1' apply(false)
|
||||
}
|
||||
gradle.settingsEvaluated {
|
||||
apply plugin: 'com.gradle.enterprise'
|
||||
gradleEnterprise {
|
||||
server = '$mockScansServer.address'
|
||||
buildScan {
|
||||
publishAlways()
|
||||
}
|
||||
}
|
||||
}
|
||||
""" + settingsFile.text
|
||||
|
||||
run(['help'], initScript, testGradleVersion.gradleVersion)
|
||||
|
||||
then:
|
||||
assertResults('help', testGradleVersion, false, true)
|
||||
|
||||
where:
|
||||
testGradleVersion << SETTINGS_PLUGIN_VERSIONS
|
||||
}
|
||||
|
||||
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean hasBuildScan, boolean scanUploadFailed = false) {
|
||||
def results = new JsonSlurper().parse(buildResultFile)
|
||||
assert results['rootProjectName'] == ROOT_PROJECT_NAME
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user