mirror of
https://github.com/gradle/actions.git
synced 2025-11-26 17:09:10 +08:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9c87d481d | ||
|
|
ff865cb801 | ||
|
|
c3acd19a4a | ||
|
|
e5bbd4c742 | ||
|
|
d7cd9fc65c | ||
|
|
6407986e96 | ||
|
|
87bf5ca2ea | ||
|
|
81b4ece56a | ||
|
|
cdbbabd09c | ||
|
|
dad038d88d | ||
|
|
621f3b3f79 | ||
|
|
4022faad7e | ||
|
|
95ef72241e | ||
|
|
169bec5d8b | ||
|
|
b9abb7b195 | ||
|
|
c04155e2ca | ||
|
|
1da1cc97d5 | ||
|
|
c401249391 | ||
|
|
a6a0c7dcef | ||
|
|
3f3913eed0 | ||
|
|
2cd2a6e951 | ||
|
|
dbbdc275be | ||
|
|
ae74429826 | ||
|
|
bdc7162ff9 | ||
|
|
31ae3562f6 | ||
|
|
719985db3d | ||
|
|
b53238971c | ||
|
|
5f1c5827bf | ||
|
|
d9336dac04 | ||
|
|
8dbe9a3802 | ||
|
|
9c3430720d | ||
|
|
30c82f0068 | ||
|
|
e3bc05f224 | ||
|
|
485ea107b7 | ||
|
|
c1091c9c8e | ||
|
|
d0a116fff5 | ||
|
|
e238a7ad22 | ||
|
|
1d2ea6e5a8 | ||
|
|
114c1c234e | ||
|
|
2db3ae936e | ||
|
|
a68381d359 | ||
|
|
52ae27f7bb | ||
|
|
d1cd62d80a | ||
|
|
af6e576724 | ||
|
|
775b4d10d7 | ||
|
|
30610bc983 | ||
|
|
d4d72c9934 | ||
|
|
96b9cb4988 | ||
|
|
db270b9337 | ||
|
|
d91e2960eb | ||
|
|
0498421560 | ||
|
|
edb13383f3 | ||
|
|
cd560aa3ad | ||
|
|
500e0ee5b3 | ||
|
|
eb13cf7170 | ||
|
|
ea14aa9caf | ||
|
|
063cfaf0eb | ||
|
|
35f9242e22 | ||
|
|
90f1de0556 | ||
|
|
da512b52a5 |
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -84,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
7
.github/workflow-samples/groovy-dsl/gradlew
vendored
7
.github/workflow-samples/groovy-dsl/gradlew
vendored
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -84,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
22
.github/workflow-samples/groovy-dsl/gradlew.bat
vendored
22
.github/workflow-samples/groovy-dsl/gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.develocity" version "3.17.2"
|
id "com.gradle.develocity" version "3.17.5"
|
||||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "2.0.1"
|
id "com.gradle.common-custom-user-data-gradle-plugin" version "2.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -84,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.apache.commons:commons-math3:3.6.1")
|
api("org.apache.commons:commons-math3:3.6.1")
|
||||||
implementation("com.google.guava:guava:33.1.0-jre")
|
implementation("com.google.guava:guava:33.2.1-jre")
|
||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
|
testImplementation("org.junit.jupiter:junit-jupiter:5.10.3")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
7
.github/workflow-samples/kotlin-dsl/gradlew
vendored
7
.github/workflow-samples/kotlin-dsl/gradlew
vendored
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -84,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
22
.github/workflow-samples/kotlin-dsl/gradlew.bat
vendored
22
.github/workflow-samples/kotlin-dsl/gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("com.gradle.develocity") version "3.17.2"
|
id("com.gradle.develocity") version "3.17.5"
|
||||||
id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
|
id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.develocity" version "3.17.2"
|
id "com.gradle.develocity" version "3.17.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
develocity {
|
develocity {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.develocity" version "3.17.2"
|
id "com.gradle.develocity" version "3.17.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
develocity {
|
develocity {
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -84,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.develocity" version "3.17.2"
|
id "com.gradle.develocity" version "3.17.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
develocity {
|
develocity {
|
||||||
|
|||||||
6
.github/workflows/ci-codeql.yml
vendored
6
.github/workflows/ci-codeql.yml
vendored
@@ -5,6 +5,12 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'main'
|
||||||
- 'release/**'
|
- 'release/**'
|
||||||
|
- 'dev/**' # Allow running Code QL on dev branches without a PR
|
||||||
|
paths-ignore:
|
||||||
|
- 'dist/**'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'dist/**'
|
- 'dist/**'
|
||||||
schedule:
|
schedule:
|
||||||
|
|||||||
2
.github/workflows/ci-integ-test.yml
vendored
2
.github/workflows/ci-integ-test.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
|||||||
cache-key-prefix: '${{ needs.determine-suite.outputs.cache-key-prefix }}-'
|
cache-key-prefix: '${{ needs.determine-suite.outputs.cache-key-prefix }}-'
|
||||||
skip-dist: ${{ needs.determine-suite.outputs.suite == 'full' }}
|
skip-dist: ${{ needs.determine-suite.outputs.suite == 'full' }}
|
||||||
secrets:
|
secrets:
|
||||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.GE_SOLUTIONS_ACCESS_TOKEN }}
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DV_SOLUTIONS_ACCESS_KEY }}
|
||||||
|
|
||||||
provision-gradle-versions:
|
provision-gradle-versions:
|
||||||
needs: [determine-suite, build-distribution]
|
needs: [determine-suite, build-distribution]
|
||||||
|
|||||||
12
.github/workflows/integ-test-cache-cleanup.yml
vendored
12
.github/workflows/integ-test-cache-cleanup.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||||
- name: Build with 3.1
|
- name: Build with 3.1
|
||||||
working-directory: sources/test/jest/resources/cache-cleanup
|
working-directory: sources/test/jest/resources/cache-cleanup
|
||||||
run: gradle --no-daemon --build-cache -Dcommons_math3_version="3.1" build
|
run: ./gradlew --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
|
# Second build will use the cache from the first build, but cleanup should remove unused artifacts
|
||||||
assemble-build:
|
assemble-build:
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
gradle-home-cache-cleanup: true
|
gradle-home-cache-cleanup: true
|
||||||
- name: Build with 3.1.1
|
- name: Build with 3.1.1
|
||||||
working-directory: sources/test/jest/resources/cache-cleanup
|
working-directory: sources/test/jest/resources/cache-cleanup
|
||||||
run: gradle --no-daemon --build-cache -Dcommons_math3_version="3.1.1" build
|
run: ./gradlew --no-daemon --build-cache -Dcommons_math3_version="3.1.1" build
|
||||||
|
|
||||||
check-clean-cache:
|
check-clean-cache:
|
||||||
needs: assemble-build
|
needs: assemble-build
|
||||||
@@ -78,7 +78,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
cache-read-only: true
|
cache-read-only: true
|
||||||
- name: Report Gradle User Home
|
- name: Report Gradle User Home
|
||||||
run: du -hc ~/.gradle/caches/modules-2
|
run: |
|
||||||
|
du -hc ~/.gradle/caches/modules-2
|
||||||
|
du -hc ~/.gradle/wrapper/dists
|
||||||
- name: Verify cleaned cache
|
- name: Verify cleaned cache
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -90,3 +92,7 @@ jobs:
|
|||||||
echo "::error ::Should NOT find commons-math3 3.1 in cache"
|
echo "::error ::Should NOT find commons-math3 3.1 in cache"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [ ! -e ~/.gradle/wrapper/dists/gradle-8.0.2-bin ]; then
|
||||||
|
echo "::error ::Should find gradle-8.0.2 in wrapper/dists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|||||||
143
.github/workflows/integ-test-inject-develocity.yml
vendored
143
.github/workflows/integ-test-inject-develocity.yml
vendored
@@ -26,14 +26,19 @@ jobs:
|
|||||||
DEVELOCITY_URL: https://ge.solutions-team.gradle.com
|
DEVELOCITY_URL: https://ge.solutions-team.gradle.com
|
||||||
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
||||||
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
||||||
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # required to test against GE plugin 3.16.2
|
${{matrix.accessKeyEnv}}: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
gradle: [current, 7.6.2, 6.9.4, 5.6.4]
|
gradle: [current, 7.6.2, 6.9.4, 5.6.4]
|
||||||
os: ${{fromJSON(inputs.runner-os)}}
|
os: ${{fromJSON(inputs.runner-os)}}
|
||||||
plugin-version: [3.16.2, 3.17.2]
|
plugin-version: [3.16.2, 3.17.5]
|
||||||
|
include:
|
||||||
|
- plugin-version: 3.16.2
|
||||||
|
accessKeyEnv: GRADLE_ENTERPRISE_ACCESS_KEY
|
||||||
|
- plugin-version: 3.17.5
|
||||||
|
accessKeyEnv: DEVELOCITY_ACCESS_KEY
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
@@ -62,3 +67,135 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
core.setFailed('No Build Scan detected')
|
core.setFailed('No Build Scan detected')
|
||||||
|
- name: Check short lived token (DEVELOCITY_ACCESS_KEY)
|
||||||
|
run: "[ ${#DEVELOCITY_ACCESS_KEY} -gt 500 ] || (echo 'DEVELOCITY_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||||
|
- name: Check short lived token (GRADLE_ENTERPRISE_ACCESS_KEY)
|
||||||
|
run: "[ ${#GRADLE_ENTERPRISE_ACCESS_KEY} -gt 500 ] || (echo 'GRADLE_ENTERPRISE_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||||
|
|
||||||
|
inject-develocity-with-access-key:
|
||||||
|
env:
|
||||||
|
DEVELOCITY_INJECTION_ENABLED: true
|
||||||
|
DEVELOCITY_URL: 'https://ge.solutions-team.gradle.com'
|
||||||
|
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
||||||
|
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
gradle: [current, 7.6.2, 6.9.4, 5.6.4]
|
||||||
|
os: ${{fromJSON(inputs.runner-os)}}
|
||||||
|
plugin-version: [3.16.2, 3.17.5]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Initialize integ-test
|
||||||
|
uses: ./.github/actions/init-integ-test
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 8
|
||||||
|
- name: Setup Gradle
|
||||||
|
id: setup-gradle
|
||||||
|
uses: ./setup-gradle
|
||||||
|
with:
|
||||||
|
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||||
|
gradle-version: ${{ matrix.gradle }}
|
||||||
|
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
develocity-token-expiry: 1
|
||||||
|
- name: Run Gradle build
|
||||||
|
id: gradle
|
||||||
|
working-directory: .github/workflow-samples/no-ge
|
||||||
|
run: gradle help
|
||||||
|
- name: Check short lived token (DEVELOCITY_ACCESS_KEY)
|
||||||
|
run: "[ ${#DEVELOCITY_ACCESS_KEY} -gt 500 ] || (echo 'DEVELOCITY_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||||
|
- name: Check short lived token (GRADLE_ENTERPRISE_ACCESS_KEY)
|
||||||
|
run: "[ ${#GRADLE_ENTERPRISE_ACCESS_KEY} -gt 500 ] || (echo 'GRADLE_ENTERPRISE_ACCESS_KEY does not look like a short lived token'; exit 1)"
|
||||||
|
- 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')
|
||||||
|
|
||||||
|
inject-develocity-short-lived-token-failed:
|
||||||
|
env:
|
||||||
|
DEVELOCITY_INJECTION_ENABLED: true
|
||||||
|
DEVELOCITY_URL: 'https://localhost:3333/'
|
||||||
|
DEVELOCITY_PLUGIN_VERSION: ${{ matrix.plugin-version }}
|
||||||
|
DEVELOCITY_CCUD_PLUGIN_VERSION: '2.0'
|
||||||
|
# Access key also set as an env var, we want to check it does not leak
|
||||||
|
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
gradle: [ current, 7.6.2, 6.9.4, 5.6.4 ]
|
||||||
|
os: ${{fromJSON(inputs.runner-os)}}
|
||||||
|
plugin-version: [ 3.16.2, 3.17.5 ]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Initialize integ-test
|
||||||
|
uses: ./.github/actions/init-integ-test
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 8
|
||||||
|
- name: Setup Gradle
|
||||||
|
id: setup-gradle
|
||||||
|
uses: ./setup-gradle
|
||||||
|
with:
|
||||||
|
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||||
|
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
- name: Run Gradle build
|
||||||
|
id: gradle
|
||||||
|
working-directory: .github/workflow-samples/no-ge
|
||||||
|
run: gradle help
|
||||||
|
- name: Check access key is not blank (DEVELOCITY_ACCESS_KEY)
|
||||||
|
run: "[ \"${DEVELOCITY_ACCESS_KEY}\" != \"\" ] || (echo 'using DEVELOCITY_ACCESS_KEY!'; exit 1)"
|
||||||
|
- name: Check access key is not blank (GRADLE_ENTERPRISE_ACCESS_KEY)
|
||||||
|
run: "[ \"${GRADLE_ENTERPRISE_ACCESS_KEY}\" != \"\" ] || (echo 'GRADLE_ENTERPRISE_ACCESS_KEY is still supported in v3!'; exit 1)"
|
||||||
|
|
||||||
|
inject-develocity-with-access-key-from-input-actions:
|
||||||
|
env:
|
||||||
|
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
gradle: [ current, 7.6.2, 6.9.4, 5.6.4 ]
|
||||||
|
os: ${{fromJSON(inputs.runner-os)}}
|
||||||
|
plugin-version: [ 3.16.2, 3.17.5 ]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Initialize integ-test
|
||||||
|
uses: ./.github/actions/init-integ-test
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 8
|
||||||
|
- name: Setup Gradle
|
||||||
|
id: setup-gradle
|
||||||
|
uses: ./setup-gradle
|
||||||
|
with:
|
||||||
|
cache-read-only: false # For testing, allow writing cache entries on non-default branches
|
||||||
|
gradle-version: ${{ matrix.gradle }}
|
||||||
|
develocity-injection-enabled: true
|
||||||
|
develocity-url: 'https://ge.solutions-team.gradle.com'
|
||||||
|
develocity-plugin-version: ${{ matrix.plugin-version }}
|
||||||
|
- 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')
|
||||||
|
|||||||
@@ -6,21 +6,6 @@ The `build` script in the project root provides a convenient way to perform many
|
|||||||
3. `./build init-scripts` will run the init-script integration tests
|
3. `./build init-scripts` will run the init-script integration tests
|
||||||
4. `./build act <act-commands>` will run `act` after building local changes (see below)
|
4. `./build act <act-commands>` will run `act` after building local changes (see below)
|
||||||
|
|
||||||
## How to merge a Dependabot PR
|
|
||||||
|
|
||||||
The "distribution" for a GitHub Action is checked into the repository itself.
|
|
||||||
In the case of these actions, 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. In the `sources` directory, run `npm install` to download NPM dependencies
|
|
||||||
3. In the `sources` directory, 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
|
|
||||||
|
|
||||||
## Using `act` to run integ-test workflows locally
|
## Using `act` to run integ-test workflows locally
|
||||||
|
|
||||||
It's possible to run GitHub Actions workflows locally with https://nektosact.com/.
|
It's possible to run GitHub Actions workflows locally with https://nektosact.com/.
|
||||||
@@ -36,7 +21,6 @@ Example running a single job:
|
|||||||
`./build act -W .github/workflows/integ-test-caching-config.yml -j cache-disabled-pre-existing-gradle-home`
|
`./build act -W .github/workflows/integ-test-caching-config.yml -j cache-disabled-pre-existing-gradle-home`
|
||||||
|
|
||||||
Known issues:
|
Known issues:
|
||||||
- `integ-test-cache-cleanup.yml` fails because `gradle` is not installed on the runner. Should be fixed by #33.
|
|
||||||
- `integ-test-detect-java-toolchains.yml` fails when running on a `linux/amd64` container, since the expected pre-installed JDKs are not present. Should be fixed by #89.
|
- `integ-test-detect-java-toolchains.yml` fails when running on a `linux/amd64` container, since the expected pre-installed JDKs are not present. Should be fixed by #89.
|
||||||
- `act` is not yet compatible with `actions/upload-artifact@v4` (or related toolkit functions)
|
- `act` is not yet compatible with `actions/upload-artifact@v4` (or related toolkit functions)
|
||||||
- See https://github.com/nektos/act/pull/2224
|
- See https://github.com/nektos/act/pull/2224
|
||||||
|
|||||||
8
build
8
build
@@ -16,12 +16,18 @@ case "$1" in
|
|||||||
# Run act
|
# Run act
|
||||||
$@
|
$@
|
||||||
# Revert the changes to the dist directory
|
# Revert the changes to the dist directory
|
||||||
git co -- dist
|
git checkout -- dist
|
||||||
;;
|
;;
|
||||||
init-scripts)
|
init-scripts)
|
||||||
cd test/init-scripts
|
cd test/init-scripts
|
||||||
./gradlew check
|
./gradlew check
|
||||||
;;
|
;;
|
||||||
|
dist)
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
cd ..
|
||||||
|
cp -r sources/dist .
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
npm install
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
|
|||||||
@@ -125,6 +125,14 @@ inputs:
|
|||||||
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
|
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
develocity-access-key:
|
||||||
|
description: Develocity access key. Should be set to a secret containing the Develocity Access key.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-token-expiry:
|
||||||
|
description: The Develocity short-lived access tokens expiry in hours. Default is 2 hours.
|
||||||
|
required: false
|
||||||
|
|
||||||
# DEPRECATED ACTION INPUTS
|
# DEPRECATED ACTION INPUTS
|
||||||
build-scan-terms-of-service-url:
|
build-scan-terms-of-service-url:
|
||||||
description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service'.
|
description: The URL to the Build Scan® terms of use. This input must be set to 'https://gradle.com/terms-of-service'.
|
||||||
|
|||||||
530
dist/dependency-submission/main/index.js
vendored
530
dist/dependency-submission/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dependency-submission/main/index.js.map
vendored
2
dist/dependency-submission/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
3262
dist/dependency-submission/post/index.js
vendored
3262
dist/dependency-submission/post/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dependency-submission/post/index.js.map
vendored
2
dist/dependency-submission/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
530
dist/setup-gradle/main/index.js
vendored
530
dist/setup-gradle/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/setup-gradle/main/index.js.map
vendored
2
dist/setup-gradle/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
3386
dist/setup-gradle/post/index.js
vendored
3386
dist/setup-gradle/post/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/setup-gradle/post/index.js.map
vendored
2
dist/setup-gradle/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
50
dist/wrapper-validation/main/index.js
vendored
50
dist/wrapper-validation/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/wrapper-validation/main/index.js.map
vendored
2
dist/wrapper-validation/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -13,7 +13,7 @@ The generated dependency graph includes all of the dependencies in your build, a
|
|||||||
for vulnerable dependencies, as well as to populate the
|
for vulnerable dependencies, as well as to populate the
|
||||||
[Dependency Graph insights view](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#viewing-the-dependency-graph).
|
[Dependency Graph insights view](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#viewing-the-dependency-graph).
|
||||||
|
|
||||||
If your confused by the behaviour you're seeing or have specific questions, please check out [the FAQ](dependency-submission-faq.md) before raising an issue.
|
If you're confused by the behaviour you're seeing or have specific questions, please check out [the FAQ](dependency-submission-faq.md) before raising an issue.
|
||||||
|
|
||||||
## General usage
|
## General usage
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ In some cases, the default action configuration will not be sufficient, and addi
|
|||||||
dependency-resolution-task: myDependencyResolutionTask
|
dependency-resolution-task: myDependencyResolutionTask
|
||||||
|
|
||||||
# Additional arguments that should be passed to execute Gradle
|
# Additional arguments that should be passed to execute Gradle
|
||||||
additonal-arguments: --no-configuration-cache
|
additional-arguments: --no-configuration-cache
|
||||||
|
|
||||||
# Enable configuration-cache reuse for this build.
|
# Enable configuration-cache reuse for this build.
|
||||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||||
@@ -367,6 +367,7 @@ on:
|
|||||||
types: [completed]
|
types: [completed]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
actions: read
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ The exact syntax depends on whether or not your project is configured with the [
|
|||||||
- name: Setup Gradle for a non-wrapper project
|
- name: Setup Gradle for a non-wrapper project
|
||||||
uses: gradle/actions/setup-gradle@v3
|
uses: gradle/actions/setup-gradle@v3
|
||||||
with:
|
with:
|
||||||
gradle-version: 8.7
|
gradle-version: 8.9
|
||||||
|
|
||||||
- name: Assemble the project
|
- name: Assemble the project
|
||||||
run: gradle assemble
|
run: gradle assemble
|
||||||
@@ -143,3 +143,8 @@ to this:
|
|||||||
build-scan-terms-of-use-agree: "yes"
|
build-scan-terms-of-use-agree: "yes"
|
||||||
```
|
```
|
||||||
These deprecated build-scan parameters are scheduled to be removed in `setup-gradle@v4` and `dependency-submission@v4`.
|
These deprecated build-scan parameters are scheduled to be removed in `setup-gradle@v4` and `dependency-submission@v4`.
|
||||||
|
|
||||||
|
## The GRADLE_ENTERPRISE_ACCESS_KEY env var is deprecated
|
||||||
|
Gradle Enterprise has been renamed to Develocity starting from Gradle plugin 3.17 and Develocity server 2024.1.
|
||||||
|
In v4 release of the action, it will require setting the access key with the `develocity-access-key` input and Develocity 2024.1 at least to generate short-lived tokens.
|
||||||
|
If those requirements are not met, the `GRADLE_ENTERPRISE_ACCESS_KEY` env var will be cleared out and build scan publication or other authenticated Develocity operations won't be possible.
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ jobs:
|
|||||||
```
|
```
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> The configuration cache cannot be saved or restored in workflows triggered by a pull requests from a repsitory fork.
|
> The configuration cache cannot be saved or restored in workflows triggered by a pull requests from a repository fork.
|
||||||
> This is because [GitHub secrets are not passed to workflows triggered by PRs from forks](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow).
|
> This is because [GitHub secrets are not passed to workflows triggered by PRs from forks](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow).
|
||||||
> This prevents a malicious PR from reading the configuration-cache data, which may encode secrets read by Gradle.
|
> This prevents a malicious PR from reading the configuration-cache data, which may encode secrets read by Gradle.
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ Using either of these mechanisms may interfere with the caching provided by this
|
|||||||
|
|
||||||
The GitHub Actions cache has some properties that present problems for efficient caching of the Gradle User Home.
|
The GitHub Actions cache has some properties that present problems for efficient caching of the Gradle User Home.
|
||||||
- Immutable entries: once a cache entry is written for a key, it cannot be overwritten or changed.
|
- Immutable entries: once a cache entry is written for a key, it cannot be overwritten or changed.
|
||||||
- Branch scope: cache entries written for a Git branch are not visible from actions running against different branches. Entries written for the default branch are visible to all. https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
|
- Branch scope: cache entries written for a Git branch are not visible from actions running against different branches or tags. Entries written for the default branch are visible to all. https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
|
||||||
- Restore keys: if no exact match is found, a set of partial keys can be provided that will match by cache key prefix. https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
|
- Restore keys: if no exact match is found, a set of partial keys can be provided that will match by cache key prefix. https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
|
||||||
|
|
||||||
Each of these properties has influenced the design and implementation of the caching in `setup-gradle`, as described below.
|
Each of these properties has influenced the design and implementation of the caching in `setup-gradle`, as described below.
|
||||||
@@ -316,8 +316,8 @@ Some techniques can be used to avoid/mitigate this issue:
|
|||||||
|
|
||||||
### Select which branches should write to the cache
|
### Select which branches should write to the cache
|
||||||
|
|
||||||
GitHub cache entries are not shared between builds on different branches.
|
GitHub cache entries are not shared between builds on different branches or tags.
|
||||||
Workflow runs can restore caches created in either the current branch or the default branch (usually main).
|
Workflow runs can _only_ restore caches created in either the same branch or the default branch (usually `main`).
|
||||||
This means that each branch will have its own Gradle User Home cache scope, and will not benefit from cache entries written for other (non-default) branches.
|
This means that each branch will have its own Gradle User Home cache scope, and will not benefit from cache entries written for other (non-default) branches.
|
||||||
|
|
||||||
By default, The `setup-gradle` action will only _write_ to the cache for builds run on the default (`master`/`main`) branch.
|
By default, The `setup-gradle` action will only _write_ to the cache for builds run on the default (`master`/`main`) branch.
|
||||||
@@ -708,27 +708,49 @@ The same auto-injection behavior is available for the Common Custom User Data Gr
|
|||||||
|
|
||||||
## Enabling Develocity injection
|
## Enabling Develocity injection
|
||||||
|
|
||||||
To enable Develocity injection for your build, you must provide the required configuration via environment variables.
|
To enable Develocity injection for your build, you must provide the required configuration via inputs.
|
||||||
|
|
||||||
Here's a minimal example:
|
Here's a minimal example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Setup Gradle
|
- name: Setup Gradle
|
||||||
uses: gradle/actions/setup-gradle@v3
|
uses: gradle/actions/setup-gradle@v3
|
||||||
|
with:
|
||||||
|
develocity-injection-enabled: true
|
||||||
|
develocity-url: https://develocity.your-server.com
|
||||||
|
develocity-plugin-version: 3.17.5
|
||||||
|
|
||||||
|
- name: Run a Gradle build with Develocity injection enabled
|
||||||
|
run: ./gradlew build
|
||||||
|
```
|
||||||
|
|
||||||
|
This configuration will automatically apply `v3.17.5` of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/), and publish build scans to https://develocity.your-server.com.
|
||||||
|
|
||||||
|
This example assumes that the `develocity.your-server.com` server allows anonymous publishing of build scans.
|
||||||
|
In the likely scenario that your Develocity server requires authentication, you will also need to pass a valid [Develocity access key](https://docs.gradle.com/develocity/gradle-plugin/#via_environment_variable) taken from a secret:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v3
|
||||||
|
with:
|
||||||
|
develocity-access-key: ${{ secrets.MY_DEVELOCITY_ACCESS_KEY }}
|
||||||
|
|
||||||
- name: Run a Gradle build with Develocity injection enabled
|
- name: Run a Gradle build with Develocity injection enabled
|
||||||
run: ./gradlew build
|
run: ./gradlew build
|
||||||
env:
|
env:
|
||||||
DEVELOCITY_INJECTION_ENABLED: true
|
DEVELOCITY_INJECTION_ENABLED: true
|
||||||
DEVELOCITY_URL: https://develocity.your-server.com
|
DEVELOCITY_URL: https://develocity.your-server.com
|
||||||
DEVELOCITY_PLUGIN_VERSION: 3.17.2
|
DEVELOCITY_PLUGIN_VERSION: 3.17
|
||||||
```
|
```
|
||||||
|
|
||||||
This configuration will automatically apply `v3.17.2` of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/), and publish build scans to https://develocity.your-server.com.
|
This access key will be used during the action execution to get a short-lived token and set it to the DEVELOCITY_ACCESS_KEY environment variable.
|
||||||
|
|
||||||
This example assumes that the `develocity.your-server.com` server allows anonymous publishing of build scans.
|
### Short-lived access tokens
|
||||||
In the likely scenario that your Develocity server requires authentication, you will also need to configure an additional environment variable
|
Develocity access keys are long-lived, creating risks if they are leaked. To avoid this, users can use short-lived access tokens to authenticate with Develocity. Access tokens can be used wherever an access key would be used. Access tokens are only valid for the Develocity instance that created them.
|
||||||
with a valid [Develocity access key](https://docs.gradle.com/develocity/gradle-plugin/#via_environment_variable).
|
If a short-lived token fails to be retrieved (for example, if the Develocity server version is lower than `2024.1`):
|
||||||
|
- if a `GRADLE_ENTERPRISE_ACCESS_KEY` env var has been set, we're falling back to it with a deprecation warning
|
||||||
|
- otherwise no access key env var will be set. In that case Develocity authenticated operations like build cache read/write and build scan publication will fail without failing the build.
|
||||||
|
For more information on short-lived tokens, see [Develocity API documentation](https://docs.gradle.com/develocity/api-manual/#short_lived_access_tokens).
|
||||||
|
|
||||||
## Configuring Develocity injection
|
## Configuring Develocity injection
|
||||||
|
|
||||||
@@ -736,16 +758,46 @@ The `init-script` supports several additional configuration parameters that you
|
|||||||
|
|
||||||
| Variable | Required | Description |
|
| Variable | Required | Description |
|
||||||
|--------------------------------------| --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|--------------------------------------| --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| DEVELOCITY_INJECTION_ENABLED | :white_check_mark: | enables Develocity injection |
|
| develocity-injection-enabled | :white_check_mark: | enables Develocity injection |
|
||||||
| DEVELOCITY_URL | :white_check_mark: | the URL of the Develocity server |
|
| develocity-url | :white_check_mark: | the URL of the Develocity server |
|
||||||
| DEVELOCITY_ALLOW_UNTRUSTED_SERVER | | allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed certificate |
|
| develocity-allow-untrusted-server | | allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed certificate |
|
||||||
| DEVELOCITY_CAPTURE_FILE_FINGERPRINTS | | enables capturing the paths and content hashes of each individual input file |
|
| develocity-capture-file-fingerprints | | enables capturing the paths and content hashes of each individual input file |
|
||||||
| DEVELOCITY_ENFORCE_URL | | enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL |
|
| develocity-enforce-url | | enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL |
|
||||||
| DEVELOCITY_PLUGIN_VERSION | :white_check_mark: | the version of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/) to apply |
|
| develocity-plugin-version | :white_check_mark: | the version of the [Develocity Gradle plugin](https://docs.gradle.com/develocity/gradle-plugin/) to apply |
|
||||||
| DEVELOCITY_CCUD_PLUGIN_VERSION | | the version of the [Common Custom User Data Gradle plugin](https://github.com/gradle/common-custom-user-data-gradle-plugin) to apply, if any |
|
| develocity-ccud-plugin-version | | the version of the [Common Custom User Data Gradle plugin](https://github.com/gradle/common-custom-user-data-gradle-plugin) to apply, if any |
|
||||||
| GRADLE_PLUGIN_REPOSITORY_URL | | the URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default |
|
| gradle-plugin-repository-url | | the URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default |
|
||||||
| GRADLE_PLUGIN_REPOSITORY_USERNAME | | the username for the repository URL to use when resolving the Develocity and CCUD plugins |
|
| gradle-plugin-repository-username | | the username for the repository URL to use when resolving the Develocity and CCUD plugins |
|
||||||
| GRADLE_PLUGIN_REPOSITORY_PASSWORD | | the password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable |
|
| gradle-plugin-repository-password | | the password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable |
|
||||||
|
|
||||||
|
The input parameters can be expressed as environment variables following the relationships outlined in the table below:
|
||||||
|
|
||||||
|
| Input | Environment Variable |
|
||||||
|
|--------------------------------------|--------------------------------------|
|
||||||
|
| develocity-injection-enabled | DEVELOCITY_INJECTION_ENABLED |
|
||||||
|
| develocity-url | DEVELOCITY_URL |
|
||||||
|
| develocity-allow-untrusted-server | DEVELOCITY_ALLOW_UNTRUSTED_SERVER |
|
||||||
|
| develocity-capture-file-fingerprints | DEVELOCITY_CAPTURE_FILE_FINGERPRINTS |
|
||||||
|
| develocity-enforce-url | DEVELOCITY_ENFORCE_URL |
|
||||||
|
| develocity-plugin-version | DEVELOCITY_PLUGIN_VERSION |
|
||||||
|
| develocity-ccud-plugin-version | DEVELOCITY_CCUD_PLUGIN_VERSION |
|
||||||
|
| gradle-plugin-repository-url | GRADLE_PLUGIN_REPOSITORY_URL |
|
||||||
|
| gradle-plugin-repository-username | GRADLE_PLUGIN_REPOSITORY_USERNAME |
|
||||||
|
| gradle-plugin-repository-password | GRADLE_PLUGIN_REPOSITORY_PASSWORD |
|
||||||
|
|
||||||
|
|
||||||
|
Here's an example using the env vars:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v3
|
||||||
|
|
||||||
|
- name: Run a Gradle build with Develocity injection enabled with environment variables
|
||||||
|
run: ./gradlew build
|
||||||
|
env:
|
||||||
|
DEVELOCITY_INJECTION_ENABLED: true
|
||||||
|
DEVELOCITY_URL: https://develocity.your-server.com
|
||||||
|
DEVELOCITY_PLUGIN_VERSION: 3.17.5
|
||||||
|
```
|
||||||
|
|
||||||
## Publishing to scans.gradle.com
|
## Publishing to scans.gradle.com
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,54 @@ inputs:
|
|||||||
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
|
description: Indicate that you agree to the Build Scan® terms of use. This input value must be "yes".
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
develocity-access-key:
|
||||||
|
description: Develocity access key. Should be set to a secret containing the Develocity Access key.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-token-expiry:
|
||||||
|
description: The Develocity short-lived access tokens expiry in hours. Default is 2 hours.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-injection-enabled:
|
||||||
|
description: Enables Develocity injection.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-url:
|
||||||
|
description: The URL for the Develocity server.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-allow-untrusted-server:
|
||||||
|
description: Allow communication with an untrusted server; set to _true_ if your Develocity instance is using a self-signed.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-capture-file-fingerprints:
|
||||||
|
description: Enables capturing the paths and content hashes of each individual input file.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-enforce-url:
|
||||||
|
description: Enforce the configured Develocity URL over a URL configured in the project's build; set to _true_ to enforce publication of build scans to the configured Develocity URL.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-plugin-version:
|
||||||
|
description: The version of the Develocity Gradle plugin to apply.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
develocity-ccud-plugin-version:
|
||||||
|
description: The version of the Common Custom User Data Gradle plugin to apply, if any.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
gradle-plugin-repository-url:
|
||||||
|
description: The URL of the repository to use when resolving the Develocity and CCUD plugins; the Gradle Plugin Portal is used by default.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
gradle-plugin-repository-username:
|
||||||
|
description: The username for the repository URL to use when resolving the Develocity and CCUD.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
gradle-plugin-repository-password:
|
||||||
|
description: The password for the repository URL to use when resolving the Develocity and CCUD plugins; Consider using secrets to pass the value to this variable.
|
||||||
|
required: false
|
||||||
|
|
||||||
# Wrapper validation configuration
|
# Wrapper validation configuration
|
||||||
validate-wrappers:
|
validate-wrappers:
|
||||||
description: |
|
description: |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Configuration file for asdf version manager
|
# Configuration file for asdf version manager
|
||||||
nodejs 20.10.0
|
nodejs 20.10.0
|
||||||
gradle 8.7
|
gradle 8.9
|
||||||
|
|||||||
28
sources/package-lock.json
generated
28
sources/package-lock.json
generated
@@ -3316,12 +3316,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -4736,9 +4736,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
@@ -11628,12 +11628,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"braces": {
|
"braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
@@ -12659,9 +12659,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import * as core from '@actions/core'
|
|
||||||
import {BuildScanConfig} from './configuration'
|
|
||||||
|
|
||||||
export function setup(config: BuildScanConfig): void {
|
|
||||||
maybeExportVariable('DEVELOCITY_INJECTION_INIT_SCRIPT_NAME', 'gradle-actions.inject-develocity.init.gradle')
|
|
||||||
maybeExportVariable('DEVELOCITY_AUTO_INJECTION_CUSTOM_VALUE', 'gradle-actions')
|
|
||||||
if (config.getBuildScanPublishEnabled()) {
|
|
||||||
maybeExportVariable('DEVELOCITY_INJECTION_ENABLED', 'true')
|
|
||||||
maybeExportVariable('DEVELOCITY_PLUGIN_VERSION', '3.17.2')
|
|
||||||
maybeExportVariable('DEVELOCITY_CCUD_PLUGIN_VERSION', '2.0')
|
|
||||||
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_URL', config.getBuildScanTermsOfUseUrl())
|
|
||||||
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_AGREE', config.getBuildScanTermsOfUseAgree())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function maybeExportVariable(variableName: string, value: unknown): void {
|
|
||||||
if (!process.env[variableName]) {
|
|
||||||
core.exportVariable(variableName, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as exec from '@actions/exec'
|
|
||||||
import * as glob from '@actions/glob'
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import {provisionAndMaybeExecute} from '../execution/gradle'
|
||||||
|
|
||||||
export class CacheCleaner {
|
export class CacheCleaner {
|
||||||
private readonly gradleUserHome: string
|
private readonly gradleUserHome: string
|
||||||
@@ -13,25 +12,20 @@ export class CacheCleaner {
|
|||||||
this.tmpDir = tmpDir
|
this.tmpDir = tmpDir
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepare(): Promise<void> {
|
async prepare(): Promise<string> {
|
||||||
// Reset the file-access journal so that files appear not to have been used recently
|
// Save the current timestamp
|
||||||
fs.rmSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true, force: true})
|
const timestamp = Date.now().toString()
|
||||||
fs.mkdirSync(path.resolve(this.gradleUserHome, 'caches/journal-1'), {recursive: true})
|
core.saveState('clean-timestamp', timestamp)
|
||||||
fs.writeFileSync(
|
return timestamp
|
||||||
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> {
|
async forceCleanup(): Promise<void> {
|
||||||
// Age all 'gc' files so that cache cleanup will run immediately.
|
const cleanTimestamp = core.getState('clean-timestamp')
|
||||||
await this.ageAllFiles('gc.properties')
|
await this.forceCleanupFilesOlderThan(cleanTimestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
async forceCleanupFilesOlderThan(cleanTimestamp: string): Promise<void> {
|
||||||
|
core.info(`Cleaning up caches before ${cleanTimestamp}`)
|
||||||
|
|
||||||
// Run a dummy Gradle build to trigger cache cleanup
|
// Run a dummy Gradle build to trigger cache cleanup
|
||||||
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
||||||
@@ -40,30 +34,37 @@ export class CacheCleaner {
|
|||||||
path.resolve(cleanupProjectDir, 'settings.gradle'),
|
path.resolve(cleanupProjectDir, 'settings.gradle'),
|
||||||
'rootProject.name = "dummy-cleanup-project"'
|
'rootProject.name = "dummy-cleanup-project"'
|
||||||
)
|
)
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.resolve(cleanupProjectDir, 'init.gradle'),
|
||||||
|
`
|
||||||
|
beforeSettings { settings ->
|
||||||
|
def cleanupTime = ${cleanTimestamp}
|
||||||
|
|
||||||
|
settings.caches {
|
||||||
|
cleanup = Cleanup.ALWAYS
|
||||||
|
|
||||||
|
releasedWrappers.removeUnusedEntriesOlderThan.set(cleanupTime)
|
||||||
|
snapshotWrappers.removeUnusedEntriesOlderThan.set(cleanupTime)
|
||||||
|
downloadedResources.removeUnusedEntriesOlderThan.set(cleanupTime)
|
||||||
|
createdResources.removeUnusedEntriesOlderThan.set(cleanupTime)
|
||||||
|
buildCache.removeUnusedEntriesOlderThan.set(cleanupTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
)
|
||||||
fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}')
|
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 provisionAndMaybeExecute('current', cleanupProjectDir, [
|
||||||
await exec.exec(gradleCommand, [], {
|
'-g',
|
||||||
cwd: cleanupProjectDir
|
this.gradleUserHome,
|
||||||
})
|
'-I',
|
||||||
}
|
'init.gradle',
|
||||||
|
'--info',
|
||||||
private async ageAllFiles(fileName = '*'): Promise<void> {
|
'--no-daemon',
|
||||||
core.debug(`Aging all files in Gradle User Home with name ${fileName}`)
|
'--no-scan',
|
||||||
await this.setUtimes(`${this.gradleUserHome}/**/${fileName}`, new Date(0))
|
'--build-cache',
|
||||||
}
|
'-DGITHUB_DEPENDENCY_GRAPH_ENABLED=false',
|
||||||
|
'noop'
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,6 +188,9 @@ export enum JobSummaryOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class BuildScanConfig {
|
export class BuildScanConfig {
|
||||||
|
static DevelocityAccessKeyEnvVar = 'DEVELOCITY_ACCESS_KEY'
|
||||||
|
static GradleEnterpriseAccessKeyEnvVar = 'GRADLE_ENTERPRISE_ACCESS_KEY'
|
||||||
|
|
||||||
getBuildScanPublishEnabled(): boolean {
|
getBuildScanPublishEnabled(): boolean {
|
||||||
return getBooleanInput('build-scan-publish') && this.verifyTermsOfUseAgreement()
|
return getBooleanInput('build-scan-publish') && this.verifyTermsOfUseAgreement()
|
||||||
}
|
}
|
||||||
@@ -200,6 +203,59 @@ export class BuildScanConfig {
|
|||||||
return this.getTermsOfUseProp('build-scan-terms-of-use-agree', 'build-scan-terms-of-service-agree')
|
return this.getTermsOfUseProp('build-scan-terms-of-use-agree', 'build-scan-terms-of-service-agree')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDevelocityAccessKey(): string {
|
||||||
|
return (
|
||||||
|
core.getInput('develocity-access-key') ||
|
||||||
|
process.env[BuildScanConfig.DevelocityAccessKeyEnvVar] ||
|
||||||
|
process.env[BuildScanConfig.GradleEnterpriseAccessKeyEnvVar] ||
|
||||||
|
''
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityTokenExpiry(): string {
|
||||||
|
return core.getInput('develocity-token-expiry')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityInjectionEnabled(): boolean | undefined {
|
||||||
|
return getOptionalBooleanInput('develocity-injection-enabled')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityUrl(): string {
|
||||||
|
return core.getInput('develocity-url')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityAllowUntrustedServer(): boolean | undefined {
|
||||||
|
return getOptionalBooleanInput('develocity-allow-untrusted-server')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityCaptureFileFingerprints(): boolean | undefined {
|
||||||
|
return getOptionalBooleanInput('develocity-capture-file-fingerprints')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityEnforceUrl(): boolean | undefined {
|
||||||
|
return getOptionalBooleanInput('develocity-enforce-url')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityPluginVersion(): string {
|
||||||
|
return core.getInput('develocity-plugin-version')
|
||||||
|
}
|
||||||
|
|
||||||
|
getDevelocityCcudPluginVersion(): string {
|
||||||
|
return core.getInput('develocity-ccud-plugin-version')
|
||||||
|
}
|
||||||
|
|
||||||
|
getGradlePluginRepositoryUrl(): string {
|
||||||
|
return core.getInput('gradle-plugin-repository-url')
|
||||||
|
}
|
||||||
|
|
||||||
|
getGradlePluginRepositoryUsername(): string {
|
||||||
|
return core.getInput('gradle-plugin-repository-username')
|
||||||
|
}
|
||||||
|
|
||||||
|
getGradlePluginRepositoryPassword(): string {
|
||||||
|
return core.getInput('gradle-plugin-repository-password')
|
||||||
|
}
|
||||||
|
|
||||||
private verifyTermsOfUseAgreement(): boolean {
|
private verifyTermsOfUseAgreement(): boolean {
|
||||||
if (
|
if (
|
||||||
(this.getBuildScanTermsOfUseUrl() !== 'https://gradle.com/terms-of-service' &&
|
(this.getBuildScanTermsOfUseUrl() !== 'https://gradle.com/terms-of-service' &&
|
||||||
@@ -313,3 +369,11 @@ function getBooleanInput(paramName: string, paramDefault = false): boolean {
|
|||||||
}
|
}
|
||||||
throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`)
|
throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOptionalBooleanInput(paramName: string): boolean | undefined {
|
||||||
|
const paramValue = core.getInput(paramName)
|
||||||
|
if (paramValue === '') {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return getBooleanInput(paramName)
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,44 +60,19 @@ export async function complete(config: DependencyGraphConfig): Promise<void> {
|
|||||||
return
|
return
|
||||||
case DependencyGraphOption.GenerateAndSubmit:
|
case DependencyGraphOption.GenerateAndSubmit:
|
||||||
case DependencyGraphOption.Clear: // Submit the empty dependency graph
|
case DependencyGraphOption.Clear: // Submit the empty dependency graph
|
||||||
await submitDependencyGraphs(await findDependencyGraphFiles())
|
await findAndSubmitDependencyGraphs(config)
|
||||||
return
|
return
|
||||||
case DependencyGraphOption.GenerateAndUpload:
|
case DependencyGraphOption.GenerateAndUpload:
|
||||||
await uploadDependencyGraphs(await findDependencyGraphFiles(), config)
|
await findAndUploadDependencyGraphs(config)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
warnOrFail(config, option, e)
|
warnOrFail(config, option, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadDependencyGraphs(dependencyGraphFiles: string[], config: DependencyGraphConfig): Promise<void> {
|
|
||||||
if (dependencyGraphFiles.length === 0) {
|
|
||||||
core.info('No dependency graph files found to upload.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRunningInActEnvironment()) {
|
|
||||||
core.info('Dependency graph upload not supported in the ACT environment.')
|
|
||||||
core.info(`Would upload: ${dependencyGraphFiles.join(', ')}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const workspaceDirectory = getWorkspaceDirectory()
|
|
||||||
|
|
||||||
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: config.getArtifactRetentionDays()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function downloadAndSubmitDependencyGraphs(config: DependencyGraphConfig): Promise<void> {
|
async function downloadAndSubmitDependencyGraphs(config: DependencyGraphConfig): Promise<void> {
|
||||||
if (isRunningInActEnvironment()) {
|
if (isRunningInActEnvironment()) {
|
||||||
core.info('Dependency graph download and submit not supported in the ACT environment.')
|
core.info('Dependency graph not supported in the ACT environment.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,53 +83,32 @@ async function downloadAndSubmitDependencyGraphs(config: DependencyGraphConfig):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<void> {
|
async function findAndSubmitDependencyGraphs(config: DependencyGraphConfig): Promise<void> {
|
||||||
if (dependencyGraphFiles.length === 0) {
|
|
||||||
core.info('No dependency graph files found to submit.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRunningInActEnvironment()) {
|
if (isRunningInActEnvironment()) {
|
||||||
core.info('Dependency graph submit not supported in the ACT environment.')
|
core.info('Dependency graph not supported in the ACT environment.')
|
||||||
core.info(`Would submit: ${dependencyGraphFiles.join(', ')}`)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const dependencyGraphFile of dependencyGraphFiles) {
|
const dependencyGraphFiles = await findDependencyGraphFiles()
|
||||||
try {
|
try {
|
||||||
await submitDependencyGraphFile(dependencyGraphFile)
|
await submitDependencyGraphs(dependencyGraphFiles)
|
||||||
} catch (error) {
|
} catch (e) {
|
||||||
if (error instanceof RequestError) {
|
try {
|
||||||
error.message = translateErrorMessage(dependencyGraphFile, error)
|
await uploadDependencyGraphs(dependencyGraphFiles, config)
|
||||||
}
|
} catch (uploadError) {
|
||||||
throw error
|
core.info(String(uploadError))
|
||||||
}
|
}
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function translateErrorMessage(jsonFile: string, error: RequestError): string {
|
async function findAndUploadDependencyGraphs(config: DependencyGraphConfig): Promise<void> {
|
||||||
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
if (isRunningInActEnvironment()) {
|
||||||
const mainWarning = `Dependency submission failed for ${relativeJsonFile}.\n${error.message}`
|
core.info('Dependency graph not supported in the ACT environment.')
|
||||||
if (error.message === 'Resource not accessible by integration') {
|
return
|
||||||
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> {
|
await uploadDependencyGraphs(await findDependencyGraphFiles(), config)
|
||||||
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[]> {
|
async function downloadDependencyGraphs(): Promise<string[]> {
|
||||||
@@ -195,6 +149,67 @@ async function findDependencyGraphFiles(): Promise<string[]> {
|
|||||||
return unprocessedFiles
|
return unprocessedFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function uploadDependencyGraphs(dependencyGraphFiles: string[], config: DependencyGraphConfig): Promise<void> {
|
||||||
|
if (dependencyGraphFiles.length === 0) {
|
||||||
|
core.info('No dependency graph files found to upload.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspaceDirectory = getWorkspaceDirectory()
|
||||||
|
|
||||||
|
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: config.getArtifactRetentionDays()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<void> {
|
||||||
|
if (dependencyGraphFiles.length === 0) {
|
||||||
|
core.info('No dependency graph files found to submit.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const dependencyGraphFile of dependencyGraphFiles) {
|
||||||
|
try {
|
||||||
|
await submitDependencyGraphFile(dependencyGraphFile)
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof RequestError) {
|
||||||
|
error.message = translateErrorMessage(dependencyGraphFile, error)
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function translateErrorMessage(jsonFile: string, error: RequestError): string {
|
||||||
|
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
||||||
|
const mainWarning = `Dependency submission failed for ${relativeJsonFile}.\n${error.message}`
|
||||||
|
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}`)
|
||||||
|
}
|
||||||
function getReportDirectory(): string {
|
function getReportDirectory(): string {
|
||||||
return process.env.DEPENDENCY_GRAPH_REPORT_DIR!
|
return process.env.DEPENDENCY_GRAPH_REPORT_DIR!
|
||||||
}
|
}
|
||||||
|
|||||||
39
sources/src/develocity/build-scan.ts
Normal file
39
sources/src/develocity/build-scan.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import * as core from '@actions/core'
|
||||||
|
import {BuildScanConfig} from '../configuration'
|
||||||
|
import {setupToken} from './short-lived-token'
|
||||||
|
|
||||||
|
export async function setup(config: BuildScanConfig): Promise<void> {
|
||||||
|
maybeExportVariable('DEVELOCITY_INJECTION_INIT_SCRIPT_NAME', 'gradle-actions.inject-develocity.init.gradle')
|
||||||
|
maybeExportVariable('DEVELOCITY_AUTO_INJECTION_CUSTOM_VALUE', 'gradle-actions')
|
||||||
|
if (config.getBuildScanPublishEnabled()) {
|
||||||
|
maybeExportVariable('DEVELOCITY_INJECTION_ENABLED', 'true')
|
||||||
|
maybeExportVariable('DEVELOCITY_PLUGIN_VERSION', '3.17.5')
|
||||||
|
maybeExportVariable('DEVELOCITY_CCUD_PLUGIN_VERSION', '2.0')
|
||||||
|
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_URL', config.getBuildScanTermsOfUseUrl())
|
||||||
|
maybeExportVariable('DEVELOCITY_TERMS_OF_USE_AGREE', config.getBuildScanTermsOfUseAgree())
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeExportVariableNotEmpty('DEVELOCITY_INJECTION_ENABLED', config.getDevelocityInjectionEnabled())
|
||||||
|
maybeExportVariableNotEmpty('DEVELOCITY_URL', config.getDevelocityUrl())
|
||||||
|
maybeExportVariableNotEmpty('DEVELOCITY_ALLOW_UNTRUSTED_SERVER', config.getDevelocityAllowUntrustedServer())
|
||||||
|
maybeExportVariableNotEmpty('DEVELOCITY_CAPTURE_FILE_FINGERPRINTS', config.getDevelocityCaptureFileFingerprints())
|
||||||
|
maybeExportVariableNotEmpty('DEVELOCITY_ENFORCE_URL', config.getDevelocityEnforceUrl())
|
||||||
|
maybeExportVariableNotEmpty('DEVELOCITY_PLUGIN_VERSION', config.getDevelocityPluginVersion())
|
||||||
|
maybeExportVariableNotEmpty('GRADLE_PLUGIN_REPOSITORY_URL', config.getGradlePluginRepositoryUrl())
|
||||||
|
maybeExportVariableNotEmpty('GRADLE_PLUGIN_REPOSITORY_USERNAME', config.getGradlePluginRepositoryUsername())
|
||||||
|
maybeExportVariableNotEmpty('GRADLE_PLUGIN_REPOSITORY_PASSWORD', config.getGradlePluginRepositoryPassword())
|
||||||
|
|
||||||
|
return setupToken(config.getDevelocityAccessKey(), config.getDevelocityTokenExpiry())
|
||||||
|
}
|
||||||
|
|
||||||
|
function maybeExportVariable(variableName: string, value: unknown): void {
|
||||||
|
if (!process.env[variableName]) {
|
||||||
|
core.exportVariable(variableName, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function maybeExportVariableNotEmpty(variableName: string, value: unknown): void {
|
||||||
|
if (value !== null && value !== undefined && value !== '') {
|
||||||
|
maybeExportVariable(variableName, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
160
sources/src/develocity/short-lived-token.ts
Normal file
160
sources/src/develocity/short-lived-token.ts
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import * as httpm from 'typed-rest-client/HttpClient'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import {BuildScanConfig} from '../configuration'
|
||||||
|
import {recordDeprecation} from '../deprecation-collector'
|
||||||
|
|
||||||
|
export async function setupToken(develocityAccessKey: string, develocityTokenExpiry: string): Promise<void> {
|
||||||
|
if (develocityAccessKey) {
|
||||||
|
try {
|
||||||
|
core.debug('Fetching short-lived token...')
|
||||||
|
const tokens = await getToken(develocityAccessKey, develocityTokenExpiry)
|
||||||
|
if (tokens != null && !tokens.isEmpty()) {
|
||||||
|
core.debug(`Got token(s), setting the access key env vars`)
|
||||||
|
const token = tokens.raw()
|
||||||
|
core.setSecret(token)
|
||||||
|
exportAccessKeyEnvVars(token)
|
||||||
|
} else {
|
||||||
|
handleMissingAccessToken()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
handleMissingAccessToken()
|
||||||
|
core.warning(`Failed to fetch short-lived token, reason: ${e}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportAccessKeyEnvVars(value: string): void {
|
||||||
|
;[BuildScanConfig.DevelocityAccessKeyEnvVar, BuildScanConfig.GradleEnterpriseAccessKeyEnvVar].forEach(key =>
|
||||||
|
core.exportVariable(key, value)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMissingAccessToken(): void {
|
||||||
|
core.warning(`Failed to fetch short-lived token for Develocity`)
|
||||||
|
|
||||||
|
if (process.env[BuildScanConfig.GradleEnterpriseAccessKeyEnvVar]) {
|
||||||
|
// We do not clear the GRADLE_ENTERPRISE_ACCESS_KEY env var in v3, to let the users upgrade to DV 2024.1
|
||||||
|
recordDeprecation(`The ${BuildScanConfig.GradleEnterpriseAccessKeyEnvVar} env var is deprecated`)
|
||||||
|
}
|
||||||
|
if (process.env[BuildScanConfig.DevelocityAccessKeyEnvVar]) {
|
||||||
|
core.warning(`The ${BuildScanConfig.DevelocityAccessKeyEnvVar} env var should be mapped to a short-lived token`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getToken(accessKey: string, expiry: string): Promise<DevelocityAccessCredentials | null> {
|
||||||
|
const empty: Promise<DevelocityAccessCredentials | null> = new Promise(r => r(null))
|
||||||
|
const develocityAccessKey = DevelocityAccessCredentials.parse(accessKey)
|
||||||
|
const shortLivedTokenClient = new ShortLivedTokenClient()
|
||||||
|
|
||||||
|
if (develocityAccessKey == null) {
|
||||||
|
return empty
|
||||||
|
}
|
||||||
|
const tokens = new Array<HostnameAccessKey>()
|
||||||
|
for (const k of develocityAccessKey.keys) {
|
||||||
|
try {
|
||||||
|
core.info(`Requesting short-lived Develocity access token for ${k.hostname}`)
|
||||||
|
const token = await shortLivedTokenClient.fetchToken(`https://${k.hostname}`, k, expiry)
|
||||||
|
tokens.push(token)
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore failure to obtain token
|
||||||
|
core.info(`Failed to obtain short-lived Develocity access token for ${k.hostname}: ${e}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tokens.length > 0) {
|
||||||
|
return DevelocityAccessCredentials.of(tokens)
|
||||||
|
}
|
||||||
|
return empty
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShortLivedTokenClient {
|
||||||
|
httpc = new httpm.HttpClient('gradle/actions/setup-gradle')
|
||||||
|
maxRetries = 3
|
||||||
|
retryInterval = 1000
|
||||||
|
|
||||||
|
async fetchToken(serverUrl: string, accessKey: HostnameAccessKey, expiry: string): Promise<HostnameAccessKey> {
|
||||||
|
const queryParams = expiry ? `?expiresInHours${expiry}` : ''
|
||||||
|
const sanitizedServerUrl = !serverUrl.endsWith('/') ? `${serverUrl}/` : serverUrl
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${accessKey.key}`
|
||||||
|
}
|
||||||
|
|
||||||
|
let attempts = 0
|
||||||
|
while (attempts < this.maxRetries) {
|
||||||
|
try {
|
||||||
|
const requestUrl = `${sanitizedServerUrl}api/auth/token${queryParams}`
|
||||||
|
core.debug(`Attempt ${attempts} to fetch short lived token at ${requestUrl}`)
|
||||||
|
const response = await this.httpc.post(requestUrl, '', headers)
|
||||||
|
if (response.message.statusCode === 200) {
|
||||||
|
const text = await response.readBody()
|
||||||
|
return new Promise<HostnameAccessKey>(resolve => resolve({hostname: accessKey.hostname, key: text}))
|
||||||
|
}
|
||||||
|
// This should be only 404
|
||||||
|
attempts++
|
||||||
|
if (attempts === this.maxRetries) {
|
||||||
|
return new Promise((resolve, reject) =>
|
||||||
|
reject(
|
||||||
|
new Error(
|
||||||
|
`Develocity short lived token request failed ${serverUrl} with status code ${response.message.statusCode}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
attempts++
|
||||||
|
if (attempts === this.maxRetries) {
|
||||||
|
return new Promise((resolve, reject) => reject(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await new Promise(resolve => setTimeout(resolve, this.retryInterval))
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => reject(new Error('Illegal state')))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostnameAccessKey = {
|
||||||
|
hostname: string
|
||||||
|
key: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DevelocityAccessCredentials {
|
||||||
|
static readonly accessKeyRegexp = /^([^;=\s]+=\w+)(;[^;=\s]+=\w+)*$/
|
||||||
|
readonly keys: HostnameAccessKey[]
|
||||||
|
|
||||||
|
private constructor(allKeys: HostnameAccessKey[]) {
|
||||||
|
this.keys = allKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
static of(allKeys: HostnameAccessKey[]): DevelocityAccessCredentials {
|
||||||
|
return new DevelocityAccessCredentials(allKeys)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly keyDelimiter = ';'
|
||||||
|
private static readonly hostDelimiter = '='
|
||||||
|
|
||||||
|
static parse(rawKey: string): DevelocityAccessCredentials | null {
|
||||||
|
if (!this.isValid(rawKey)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return new DevelocityAccessCredentials(
|
||||||
|
rawKey.split(this.keyDelimiter).map(hostKey => {
|
||||||
|
const pair = hostKey.split(this.hostDelimiter)
|
||||||
|
return {hostname: pair[0], key: pair[1]}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty(): boolean {
|
||||||
|
return this.keys.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
raw(): string {
|
||||||
|
return this.keys
|
||||||
|
.map(k => `${k.hostname}${DevelocityAccessCredentials.hostDelimiter}${k.key}`)
|
||||||
|
.join(DevelocityAccessCredentials.keyDelimiter)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static isValid(allKeys: string): boolean {
|
||||||
|
return this.accessKeyRegexp.test(allKeys)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ buildscript {
|
|||||||
def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url') ?: 'https://plugins.gradle.org/m2'
|
def pluginRepositoryUrl = getInputParam('gradle.plugin-repository.url') ?: 'https://plugins.gradle.org/m2'
|
||||||
def pluginRepositoryUsername = getInputParam('gradle.plugin-repository.username')
|
def pluginRepositoryUsername = getInputParam('gradle.plugin-repository.username')
|
||||||
def pluginRepositoryPassword = getInputParam('gradle.plugin-repository.password')
|
def pluginRepositoryPassword = getInputParam('gradle.plugin-repository.password')
|
||||||
def dependencyGraphPluginVersion = getInputParam('dependency-graph-plugin.version') ?: '1.3.0'
|
def dependencyGraphPluginVersion = getInputParam('dependency-graph-plugin.version') ?: '1.3.1'
|
||||||
|
|
||||||
logger.lifecycle("Resolving dependency graph plugin ${dependencyGraphPluginVersion} from plugin repository: ${pluginRepositoryUrl}")
|
logger.lifecycle("Resolving dependency graph plugin ${dependencyGraphPluginVersion} from plugin repository: ${pluginRepositoryUrl}")
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Initscript for injection of Develocity into Gradle builds.
|
||||||
|
* Version: v1.0
|
||||||
|
*/
|
||||||
|
|
||||||
import org.gradle.util.GradleVersion
|
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 Develocity plugin to the classpath so it can be applied to the build further down in this script
|
|
||||||
initscript {
|
initscript {
|
||||||
|
// NOTE: there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated
|
||||||
def isTopLevelBuild = !gradle.parent
|
def isTopLevelBuild = !gradle.parent
|
||||||
if (!isTopLevelBuild) {
|
if (!isTopLevelBuild) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
def getInputParam = { String name ->
|
def getInputParam = { String name ->
|
||||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
def ENV_VAR_PREFIX = ''
|
||||||
|
def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,9 +24,9 @@ initscript {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish early if injection is disabled
|
// Plugin loading is only required for Develocity injection. Abort early if not enabled.
|
||||||
def gradleInjectionEnabled = getInputParam("develocity.injection-enabled")
|
def develocityInjectionEnabled = Boolean.parseBoolean(getInputParam("develocity.injection-enabled"))
|
||||||
if (gradleInjectionEnabled != "true") {
|
if (!develocityInjectionEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,29 +79,17 @@ initscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
|
static getInputParam(String name) {
|
||||||
def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin'
|
def ENV_VAR_PREFIX = ''
|
||||||
|
def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_')
|
||||||
def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise'
|
return System.getProperty(name) ?: System.getenv(envVarName)
|
||||||
def GRADLE_ENTERPRISE_PLUGIN_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin'
|
}
|
||||||
|
|
||||||
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'
|
|
||||||
def DEVELOCITY_PLUGIN_CLASS = 'com.gradle.develocity.agent.gradle.DevelocityPlugin'
|
|
||||||
|
|
||||||
def CI_AUTO_INJECTION_CUSTOM_VALUE_NAME = 'CI auto injection'
|
|
||||||
def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin'
|
|
||||||
def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin'
|
|
||||||
|
|
||||||
def isTopLevelBuild = !gradle.parent
|
def isTopLevelBuild = !gradle.parent
|
||||||
if (!isTopLevelBuild) {
|
if (!isTopLevelBuild) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
def getInputParam = { String name ->
|
|
||||||
def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_')
|
|
||||||
return System.getProperty(name) ?: System.getenv(envVarName)
|
|
||||||
}
|
|
||||||
|
|
||||||
def requestedInitScriptName = getInputParam('develocity.injection.init-script-name')
|
def requestedInitScriptName = getInputParam('develocity.injection.init-script-name')
|
||||||
def initScriptName = buildscript.sourceFile.name
|
def initScriptName = buildscript.sourceFile.name
|
||||||
if (requestedInitScriptName != initScriptName) {
|
if (requestedInitScriptName != initScriptName) {
|
||||||
@@ -105,42 +97,62 @@ if (requestedInitScriptName != initScriptName) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish early if injection is disabled
|
def develocityInjectionEnabled = Boolean.parseBoolean(getInputParam("develocity.injection-enabled"))
|
||||||
def gradleInjectionEnabled = getInputParam("develocity.injection-enabled")
|
if (develocityInjectionEnabled) {
|
||||||
if (gradleInjectionEnabled != "true") {
|
enableDevelocityInjection()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def develocityUrl = getInputParam('develocity.url')
|
// To enable build-scan capture, a `captureBuildScanLink(String)` method must be added to `BuildScanCollector`.
|
||||||
def develocityAllowUntrustedServer = Boolean.parseBoolean(getInputParam('develocity.allow-untrusted-server'))
|
def buildScanCollector = new BuildScanCollector()
|
||||||
def develocityEnforceUrl = Boolean.parseBoolean(getInputParam('develocity.enforce-url'))
|
def buildScanCaptureEnabled = buildScanCollector.metaClass.respondsTo(buildScanCollector, 'captureBuildScanLink', String)
|
||||||
def buildScanUploadInBackground = Boolean.parseBoolean(getInputParam('develocity.build-scan.upload-in-background'))
|
if (buildScanCaptureEnabled) {
|
||||||
def develocityCaptureFileFingerprints = getInputParam('develocity.capture-file-fingerprints') ? Boolean.parseBoolean(getInputParam('develocity.capture-file-fingerprints')) : true
|
enableBuildScanLinkCapture(buildScanCollector)
|
||||||
def develocityPluginVersion = getInputParam('develocity.plugin.version')
|
}
|
||||||
def ccudPluginVersion = getInputParam('develocity.ccud-plugin.version')
|
|
||||||
def buildScanTermsOfUseUrl = getInputParam('develocity.terms-of-use.url')
|
|
||||||
def buildScanTermsOfUseAgree = getInputParam('develocity.terms-of-use.agree')
|
|
||||||
def ciAutoInjectionCustomValueValue = getInputParam('develocity.auto-injection.custom-value')
|
|
||||||
|
|
||||||
def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0')
|
void enableDevelocityInjection() {
|
||||||
def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0')
|
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
|
||||||
def shouldApplyDevelocityPlugin = atLeastGradle5 && develocityPluginVersion && isAtLeast(develocityPluginVersion, '3.17')
|
def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin'
|
||||||
|
|
||||||
def dvOrGe = { def dvValue, def geValue ->
|
def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise'
|
||||||
|
def GRADLE_ENTERPRISE_PLUGIN_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin'
|
||||||
|
|
||||||
|
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'
|
||||||
|
def DEVELOCITY_PLUGIN_CLASS = 'com.gradle.develocity.agent.gradle.DevelocityPlugin'
|
||||||
|
|
||||||
|
def CI_AUTO_INJECTION_CUSTOM_VALUE_NAME = 'CI auto injection'
|
||||||
|
def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin'
|
||||||
|
def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin'
|
||||||
|
|
||||||
|
def develocityUrl = getInputParam('develocity.url')
|
||||||
|
def develocityAllowUntrustedServer = Boolean.parseBoolean(getInputParam('develocity.allow-untrusted-server'))
|
||||||
|
def develocityEnforceUrl = Boolean.parseBoolean(getInputParam('develocity.enforce-url'))
|
||||||
|
def buildScanUploadInBackground = Boolean.parseBoolean(getInputParam('develocity.build-scan.upload-in-background'))
|
||||||
|
def develocityCaptureFileFingerprints = getInputParam('develocity.capture-file-fingerprints') ? Boolean.parseBoolean(getInputParam('develocity.capture-file-fingerprints')) : true
|
||||||
|
def develocityPluginVersion = getInputParam('develocity.plugin.version')
|
||||||
|
def ccudPluginVersion = getInputParam('develocity.ccud-plugin.version')
|
||||||
|
def buildScanTermsOfUseUrl = getInputParam('develocity.terms-of-use.url')
|
||||||
|
def buildScanTermsOfUseAgree = getInputParam('develocity.terms-of-use.agree')
|
||||||
|
def ciAutoInjectionCustomValueValue = getInputParam('develocity.auto-injection.custom-value')
|
||||||
|
|
||||||
|
def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0')
|
||||||
|
def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0')
|
||||||
|
def shouldApplyDevelocityPlugin = atLeastGradle5 && develocityPluginVersion && isAtLeast(develocityPluginVersion, '3.17')
|
||||||
|
|
||||||
|
def dvOrGe = { def dvValue, def geValue ->
|
||||||
if (shouldApplyDevelocityPlugin) {
|
if (shouldApplyDevelocityPlugin) {
|
||||||
return dvValue instanceof Closure<?> ? dvValue() : dvValue
|
return dvValue instanceof Closure<?> ? dvValue() : dvValue
|
||||||
}
|
}
|
||||||
return geValue instanceof Closure<?> ? geValue() : geValue
|
return geValue instanceof Closure<?> ? geValue() : geValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish early if configuration parameters passed in via system properties are not valid/supported
|
// finish early if configuration parameters passed in via system properties are not valid/supported
|
||||||
if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) {
|
if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) {
|
||||||
logger.warn("Common Custom User Data Gradle plugin must be at least 1.7. Configured version is $ccudPluginVersion.")
|
logger.warn("Common Custom User Data Gradle plugin must be at least 1.7. Configured version is $ccudPluginVersion.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// register buildScanPublished listener and optionally apply the Develocity plugin
|
// Conditionally apply and configure the Develocity plugin
|
||||||
if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
||||||
rootProject {
|
rootProject {
|
||||||
buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming ->
|
buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming ->
|
||||||
def resolutionResult = incoming.resolutionResult
|
def resolutionResult = incoming.resolutionResult
|
||||||
@@ -231,7 +243,7 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gradle.settingsEvaluated { settings ->
|
gradle.settingsEvaluated { settings ->
|
||||||
if (develocityPluginVersion) {
|
if (develocityPluginVersion) {
|
||||||
if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) && !settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
|
if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) && !settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
|
||||||
@@ -307,6 +319,7 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyPluginExternally(def pluginManager, String pluginClassName) {
|
void applyPluginExternally(def pluginManager, String pluginClassName) {
|
||||||
@@ -361,3 +374,41 @@ static boolean isAtLeast(String versionUnderTest, String referenceVersion) {
|
|||||||
static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
|
static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
|
||||||
!isAtLeast(versionUnderTest, referenceVersion)
|
!isAtLeast(versionUnderTest, referenceVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enableBuildScanLinkCapture(BuildScanCollector collector) {
|
||||||
|
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
|
||||||
|
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'
|
||||||
|
|
||||||
|
// Conditionally apply and configure the Develocity plugin
|
||||||
|
if (GradleVersion.current() < GradleVersion.version('6.0')) {
|
||||||
|
rootProject {
|
||||||
|
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
|
||||||
|
// Only execute if develocity plugin isn't applied.
|
||||||
|
if (gradle.rootProject.extensions.findByName("develocity")) return
|
||||||
|
buildScanPublishedAction(buildScan, collector)
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
|
||||||
|
buildScanPublishedAction(develocity.buildScan, collector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gradle.settingsEvaluated { settings ->
|
||||||
|
eachDevelocitySettingsExtension(settings) { ext ->
|
||||||
|
buildScanPublishedAction(ext.buildScan, collector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action will only be called if a `BuildScanCollector.captureBuildScanLink` method is present.
|
||||||
|
// Add `void captureBuildScanLink(String) {}` to the `BuildScanCollector` class to respond to buildScanPublished events
|
||||||
|
static buildScanPublishedAction(def buildScanExtension, BuildScanCollector collector) {
|
||||||
|
if (buildScanExtension.metaClass.respondsTo(buildScanExtension, 'buildScanPublished', Action)) {
|
||||||
|
buildScanExtension.buildScanPublished { scan ->
|
||||||
|
collector.captureBuildScanLink(scan.buildScanUri.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BuildScanCollector {}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import * as path from 'path'
|
|||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import * as caches from './caching/caches'
|
import * as caches from './caching/caches'
|
||||||
import * as jobSummary from './job-summary'
|
import * as jobSummary from './job-summary'
|
||||||
import * as buildScan from './build-scan'
|
import * as buildScan from './develocity/build-scan'
|
||||||
|
|
||||||
import {loadBuildResults, markBuildResultsProcessed} from './build-results'
|
import {loadBuildResults, markBuildResultsProcessed} from './build-results'
|
||||||
import {CacheListener, generateCachingReport} from './caching/cache-reporting'
|
import {CacheListener, generateCachingReport} from './caching/cache-reporting'
|
||||||
@@ -41,7 +41,7 @@ export async function setup(cacheConfig: CacheConfig, buildScanConfig: BuildScan
|
|||||||
|
|
||||||
core.saveState(CACHE_LISTENER, cacheListener.stringify())
|
core.saveState(CACHE_LISTENER, cacheListener.stringify())
|
||||||
|
|
||||||
buildScan.setup(buildScanConfig)
|
await buildScan.setup(buildScanConfig)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,28 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "8.9",
|
||||||
|
"checksum": "498495120a03b9a6ab5d155f5de3c8f0d986a449153702fb80fc80e134484f17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "8.9-rc-2",
|
||||||
|
"checksum": "498495120a03b9a6ab5d155f5de3c8f0d986a449153702fb80fc80e134484f17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "8.9-rc-1",
|
||||||
|
"checksum": "498495120a03b9a6ab5d155f5de3c8f0d986a449153702fb80fc80e134484f17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "8.8",
|
||||||
|
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "8.8-rc-2",
|
||||||
|
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "8.8-rc-1",
|
||||||
|
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "8.7",
|
"version": "8.7",
|
||||||
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
"checksum": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ dependencies {
|
|||||||
testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') {
|
testImplementation ('io.ratpack:ratpack-groovy-test:1.9.0') {
|
||||||
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
|
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
|
||||||
}
|
}
|
||||||
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.17.0'
|
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.17.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
7
sources/test/init-scripts/gradlew
vendored
7
sources/test/init-scripts/gradlew
vendored
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -84,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|||||||
2
sources/test/init-scripts/gradlew.bat
vendored
2
sources/test/init-scripts/gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.gradle.develocity" version "3.17.2"
|
id "com.gradle.develocity" version "3.17.5"
|
||||||
id "com.gradle.common-custom-user-data-gradle-plugin" version "2.0.1"
|
id "com.gradle.common-custom-user-data-gradle-plugin" version "2.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import java.nio.file.Files
|
|||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
|
|
||||||
class BaseInitScriptTest extends Specification {
|
class BaseInitScriptTest extends Specification {
|
||||||
static final String DEVELOCITY_PLUGIN_VERSION = '3.17.2'
|
static final String DEVELOCITY_PLUGIN_VERSION = '3.17.5'
|
||||||
static final String CCUD_PLUGIN_VERSION = '2.0.1'
|
static final String CCUD_PLUGIN_VERSION = '2.0.1'
|
||||||
|
|
||||||
static final TestGradleVersion GRADLE_3_X = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9)
|
static final TestGradleVersion GRADLE_3_X = new TestGradleVersion(GradleVersion.version('3.5.1'), 7, 9)
|
||||||
@@ -27,7 +27,7 @@ class BaseInitScriptTest extends Specification {
|
|||||||
static final TestGradleVersion GRADLE_7_1 = new TestGradleVersion(GradleVersion.version('7.6.2'), 8, 19)
|
static final TestGradleVersion GRADLE_7_1 = new TestGradleVersion(GradleVersion.version('7.6.2'), 8, 19)
|
||||||
static final TestGradleVersion GRADLE_7_X = new TestGradleVersion(GradleVersion.version('7.6.2'), 8, 19)
|
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_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 TestGradleVersion GRADLE_8_X = new TestGradleVersion(GradleVersion.version('8.9'), 8, 22)
|
||||||
|
|
||||||
static final List<TestGradleVersion> ALL_VERSIONS = [
|
static final List<TestGradleVersion> ALL_VERSIONS = [
|
||||||
GRADLE_3_X, // First version where TestKit supports environment variables
|
GRADLE_3_X, // First version where TestKit supports environment variables
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
|
|||||||
when:
|
when:
|
||||||
settingsFile.text = """
|
settingsFile.text = """
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.gradle.develocity' version '3.17.2' apply(false)
|
id 'com.gradle.develocity' version '3.17.5' apply(false)
|
||||||
}
|
}
|
||||||
gradle.settingsEvaluated {
|
gradle.settingsEvaluated {
|
||||||
apply plugin: 'com.gradle.develocity'
|
apply plugin: 'com.gradle.develocity'
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class TestDependencyGraph extends BaseInitScriptTest {
|
|||||||
|
|
||||||
then:
|
then:
|
||||||
assert reportFile.exists()
|
assert reportFile.exists()
|
||||||
assert result.output.contains("Resolving dependency graph plugin 1.3.0 from plugin repository: https://plugins.grdev.net/m2")
|
assert result.output.find("Resolving dependency graph plugin [\\d\\.]+ from plugin repository: https://plugins.grdev.net/m2")
|
||||||
|
|
||||||
where:
|
where:
|
||||||
testGradleVersion << DEPENDENCY_GRAPH_VERSIONS
|
testGradleVersion << DEPENDENCY_GRAPH_VERSIONS
|
||||||
@@ -170,7 +170,7 @@ class TestDependencyGraph extends BaseInitScriptTest {
|
|||||||
|
|
||||||
then:
|
then:
|
||||||
assert reportFile.exists()
|
assert reportFile.exists()
|
||||||
assert result.output.contains("Resolving dependency graph plugin 1.3.0 from plugin repository: https://plugins.grdev.net/m2")
|
assert result.output.find("Resolving dependency graph plugin [\\d\\.]+ from plugin repository: https://plugins.grdev.net/m2")
|
||||||
assert result.output.contains("Applying credentials for plugin repository: https://plugins.grdev.net/m2")
|
assert result.output.contains("Applying credentials for plugin repository: https://plugins.grdev.net/m2")
|
||||||
|
|
||||||
where:
|
where:
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import * as exec from '@actions/exec'
|
import * as exec from '@actions/exec'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as glob from '@actions/glob'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import {CacheCleaner} from '../../src/caching/cache-cleaner'
|
import {CacheCleaner} from '../../src/caching/cache-cleaner'
|
||||||
@@ -13,7 +15,7 @@ test('will cleanup unused dependency jars and build-cache entries', async () =>
|
|||||||
|
|
||||||
await runGradleBuild(projectRoot, 'build', '3.1')
|
await runGradleBuild(projectRoot, 'build', '3.1')
|
||||||
|
|
||||||
await cacheCleaner.prepare()
|
const timestamp = await cacheCleaner.prepare()
|
||||||
|
|
||||||
await runGradleBuild(projectRoot, 'build', '3.1.1')
|
await runGradleBuild(projectRoot, 'build', '3.1.1')
|
||||||
|
|
||||||
@@ -23,13 +25,13 @@ test('will cleanup unused dependency jars and build-cache entries', async () =>
|
|||||||
|
|
||||||
expect(fs.existsSync(commonsMath31)).toBe(true)
|
expect(fs.existsSync(commonsMath31)).toBe(true)
|
||||||
expect(fs.existsSync(commonsMath311)).toBe(true)
|
expect(fs.existsSync(commonsMath311)).toBe(true)
|
||||||
expect(fs.readdirSync(buildCacheDir).length).toBe(6)
|
expect(fs.readdirSync(buildCacheDir).length).toBe(4) // gc.properties, build-cache-1.lock, and 2 task entries
|
||||||
|
|
||||||
await cacheCleaner.forceCleanup()
|
await cacheCleaner.forceCleanupFilesOlderThan(timestamp)
|
||||||
|
|
||||||
expect(fs.existsSync(commonsMath31)).toBe(false)
|
expect(fs.existsSync(commonsMath31)).toBe(false)
|
||||||
expect(fs.existsSync(commonsMath311)).toBe(true)
|
expect(fs.existsSync(commonsMath311)).toBe(true)
|
||||||
expect(fs.readdirSync(buildCacheDir).length).toBe(5)
|
expect(fs.readdirSync(buildCacheDir).length).toBe(3) // 1 task entry has been cleaned up
|
||||||
})
|
})
|
||||||
|
|
||||||
test('will cleanup unused gradle versions', async () => {
|
test('will cleanup unused gradle versions', async () => {
|
||||||
@@ -42,24 +44,38 @@ test('will cleanup unused gradle versions', async () => {
|
|||||||
await runGradleWrapperBuild(projectRoot, 'build')
|
await runGradleWrapperBuild(projectRoot, 'build')
|
||||||
await runGradleBuild(projectRoot, 'build')
|
await runGradleBuild(projectRoot, 'build')
|
||||||
|
|
||||||
await cacheCleaner.prepare()
|
const timestamp = await cacheCleaner.prepare()
|
||||||
|
|
||||||
// Run with only one of these versions
|
// Run with only one of these versions
|
||||||
await runGradleBuild(projectRoot, 'build')
|
await runGradleBuild(projectRoot, 'build')
|
||||||
|
|
||||||
const gradle802 = path.resolve(gradleUserHome, "caches/8.0.2")
|
const gradle802 = path.resolve(gradleUserHome, "caches/8.0.2")
|
||||||
|
const transforms3 = path.resolve(gradleUserHome, "caches/transforms-3")
|
||||||
|
const metadata100 = path.resolve(gradleUserHome, "caches/modules-2/metadata-2.100")
|
||||||
const wrapper802 = path.resolve(gradleUserHome, "wrapper/dists/gradle-8.0.2-bin")
|
const wrapper802 = path.resolve(gradleUserHome, "wrapper/dists/gradle-8.0.2-bin")
|
||||||
const gradleCurrent = path.resolve(gradleUserHome, "caches/8.7")
|
const gradleCurrent = path.resolve(gradleUserHome, "caches/8.9")
|
||||||
|
const metadataCurrent = path.resolve(gradleUserHome, "caches/modules-2/metadata-2.106")
|
||||||
|
|
||||||
expect(fs.existsSync(gradle802)).toBe(true)
|
expect(fs.existsSync(gradle802)).toBe(true)
|
||||||
|
expect(fs.existsSync(transforms3)).toBe(true)
|
||||||
|
expect(fs.existsSync(metadata100)).toBe(true)
|
||||||
expect(fs.existsSync(wrapper802)).toBe(true)
|
expect(fs.existsSync(wrapper802)).toBe(true)
|
||||||
expect(fs.existsSync(gradleCurrent)).toBe(true)
|
|
||||||
|
|
||||||
await cacheCleaner.forceCleanup()
|
expect(fs.existsSync(gradleCurrent)).toBe(true)
|
||||||
|
expect(fs.existsSync(metadataCurrent)).toBe(true)
|
||||||
|
|
||||||
|
// The wrapper won't be removed if it was recently downloaded. Age it.
|
||||||
|
setUtimes(wrapper802, new Date(Date.now() - 48 * 60 * 60 * 1000))
|
||||||
|
|
||||||
|
await cacheCleaner.forceCleanupFilesOlderThan(timestamp)
|
||||||
|
|
||||||
expect(fs.existsSync(gradle802)).toBe(false)
|
expect(fs.existsSync(gradle802)).toBe(false)
|
||||||
|
expect(fs.existsSync(transforms3)).toBe(false)
|
||||||
|
expect(fs.existsSync(metadata100)).toBe(false)
|
||||||
expect(fs.existsSync(wrapper802)).toBe(false)
|
expect(fs.existsSync(wrapper802)).toBe(false)
|
||||||
|
|
||||||
expect(fs.existsSync(gradleCurrent)).toBe(true)
|
expect(fs.existsSync(gradleCurrent)).toBe(true)
|
||||||
|
expect(fs.existsSync(metadataCurrent)).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
async function runGradleBuild(projectRoot: string, args: string, version: string = '3.1'): Promise<void> {
|
async function runGradleBuild(projectRoot: string, args: string, version: string = '3.1'): Promise<void> {
|
||||||
@@ -85,3 +101,9 @@ function prepareTestProject(): string {
|
|||||||
return projectRoot
|
return projectRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function setUtimes(pattern: string, timestamp: Date): Promise<void> {
|
||||||
|
const globber = await glob.create(pattern)
|
||||||
|
for await (const file of globber.globGenerator()) {
|
||||||
|
fs.utimesSync(file, timestamp, timestamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
117
sources/test/jest/short-lived-token.test.ts
Normal file
117
sources/test/jest/short-lived-token.test.ts
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import {DevelocityAccessCredentials, getToken} from "../../src/develocity/short-lived-token";
|
||||||
|
import nock from "nock";
|
||||||
|
|
||||||
|
describe('short lived tokens', () => {
|
||||||
|
it('parse valid access key should return an object', async () => {
|
||||||
|
let develocityAccessCredentials = DevelocityAccessCredentials.parse('some-host.local=key1;host2=key2');
|
||||||
|
|
||||||
|
expect(develocityAccessCredentials).toStrictEqual(DevelocityAccessCredentials.of([
|
||||||
|
{hostname: 'some-host.local', key: 'key1'},
|
||||||
|
{hostname: 'host2', key: 'key2'}])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parse wrong access key should return null', async () => {
|
||||||
|
let develocityAccessCredentials = DevelocityAccessCredentials.parse('random;foo');
|
||||||
|
|
||||||
|
expect(develocityAccessCredentials).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parse empty access key should return null', async () => {
|
||||||
|
let develocityAccessCredentials = DevelocityAccessCredentials.parse('');
|
||||||
|
|
||||||
|
expect(develocityAccessCredentials).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('access key as raw string', async () => {
|
||||||
|
let develocityAccessCredentials = DevelocityAccessCredentials.parse('host1=key1;host2=key2');
|
||||||
|
|
||||||
|
expect(develocityAccessCredentials?.raw()).toBe('host1=key1;host2=key2')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token fails when cannot connect', async () => {
|
||||||
|
nock('http://localhost:3333')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.times(3)
|
||||||
|
.replyWithError({
|
||||||
|
message: 'connect ECONNREFUSED 127.0.0.1:3333',
|
||||||
|
code: 'ECONNREFUSED'
|
||||||
|
})
|
||||||
|
await expect(getToken('localhost=key0', ''))
|
||||||
|
.resolves
|
||||||
|
.toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token is null when request fails', async () => {
|
||||||
|
nock('http://dev:3333')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.times(3)
|
||||||
|
.reply(500, 'Internal error')
|
||||||
|
expect.assertions(1)
|
||||||
|
await expect(getToken('dev=xyz', ''))
|
||||||
|
.resolves
|
||||||
|
.toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token returns null when access key is empty', async () => {
|
||||||
|
expect.assertions(1)
|
||||||
|
await expect(getToken('', ''))
|
||||||
|
.resolves
|
||||||
|
.toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token succeeds when single key is set', async () => {
|
||||||
|
nock('https://dev')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.reply(200, 'token')
|
||||||
|
expect.assertions(1)
|
||||||
|
await expect(getToken('dev=key1', ''))
|
||||||
|
.resolves
|
||||||
|
.toEqual({"keys": [{"hostname": "dev", "key": "token"}]})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token succeeds when multiple keys are set', async () => {
|
||||||
|
nock('https://dev')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.reply(200, 'token1')
|
||||||
|
nock('https://prod')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.reply(200, 'token2')
|
||||||
|
expect.assertions(1)
|
||||||
|
await expect(getToken('dev=key1;prod=key2', ''))
|
||||||
|
.resolves
|
||||||
|
.toEqual({"keys": [{"hostname": "dev", "key": "token1"}, {"hostname": "prod", "key": "token2"}]})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token succeeds when multiple keys are set and one is failing', async () => {
|
||||||
|
nock('https://dev')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.reply(200, 'token1')
|
||||||
|
nock('https://bogus')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.times(3)
|
||||||
|
.reply(500, 'Internal Error')
|
||||||
|
nock('https://prod')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.reply(200, 'token2')
|
||||||
|
expect.assertions(1)
|
||||||
|
await expect(getToken('dev=key1;bogus=key0;prod=key2', ''))
|
||||||
|
.resolves
|
||||||
|
.toEqual({"keys": [{"hostname": "dev", "key": "token1"}, {"hostname": "prod", "key": "token2"}]})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('get short lived token is null when multiple keys are set and all are failing', async () => {
|
||||||
|
nock('https://dev')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.times(3)
|
||||||
|
.reply(500, 'Internal Error')
|
||||||
|
nock('https://bogus')
|
||||||
|
.post('/api/auth/token')
|
||||||
|
.times(3)
|
||||||
|
.reply(500, 'Internal Error')
|
||||||
|
expect.assertions(1)
|
||||||
|
await expect(getToken('dev=key1;bogus=key0', ''))
|
||||||
|
.resolves
|
||||||
|
.toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user